คำนำ
ฤดูใบไม้ผลิระบุพฤติกรรมการแพร่กระจายการทำธุรกรรม 7 ประเภทในอินเทอร์เฟซการทำธุรกรรม พฤติกรรมการแพร่กระจายการทำธุรกรรมเป็นคุณลักษณะการเพิ่มประสิทธิภาพการทำธุรกรรมที่ไม่ซ้ำกันกับเฟรมเวิร์กสปริงและไม่ได้อยู่ในพฤติกรรมฐานข้อมูลของผู้ให้บริการธุรกรรมจริง นี่คือกล่องเครื่องมือที่ทรงพลังที่สปริงให้เราและการใช้สายการแพร่กระจายธุรกรรมสามารถให้สิ่งอำนวยความสะดวกมากมายสำหรับความพยายามในการพัฒนาของเรา แต่ผู้คนมีความเข้าใจผิดมากมายเกี่ยวกับเรื่องนี้และคุณต้องได้ยินข่าวลือว่า "ธุรกิจวิธีการบริการดีที่สุดที่จะไม่ซ้อนกัน" ในการใช้เครื่องมืออย่างถูกต้องคุณต้องเข้าใจเครื่องมือก่อน บทความนี้แนะนำพฤติกรรมการแพร่กระจายการทำธุรกรรมทั้งเจ็ดโดยละเอียดและนำเสนอตัวอย่างรหัสหลักของเนื้อหา
แนวคิดพื้นฐาน
1. พฤติกรรมการสื่อสารการทำธุรกรรมคืออะไร?
พฤติกรรมการแพร่กระจายการทำธุรกรรมใช้เพื่ออธิบายว่าการทำธุรกรรมมีการแพร่กระจายอย่างไรเมื่อวิธีการแก้ไขโดยพฤติกรรมการแพร่กระจายการทำธุรกรรมบางอย่างจะซ้อนกันในวิธีอื่น
ใช้รหัสหลอกเพื่ออธิบาย:
โมฆะสาธารณะ Methoda () {methodb (); // dosomething} @TransAction (การแพร่กระจาย = xxx) โมฆะสาธารณะ methodb () {// dosomething} วิธี methodA() ในรหัสเรียกวิธี methodB() ในซ้อนกันและพฤติกรรมการแพร่กระจายการทำธุรกรรมของ methodB() จะถูกกำหนดโดยการตั้งค่า @Transaction(Propagation=XXX) ควรสังเกตที่นี่ว่า methodA() ไม่ได้เริ่มการทำธุรกรรมและวิธีการแก้ไขพฤติกรรมการแพร่กระจายการทำธุรกรรมบางอย่างไม่จำเป็นต้องเรียกในวิธีการเริ่มต้นการทำธุรกรรม
2. เจ็ดพฤติกรรมการแพร่กระจายการทำธุรกรรมในฤดูใบไม้ผลิ
| ประเภทพฤติกรรมการแพร่กระจายการทำธุรกรรม | อธิบาย |
|---|---|
| propagation_required | หากไม่มีธุรกรรมในปัจจุบันให้สร้างธุรกรรมใหม่และหากมีการทำธุรกรรมแล้วให้เพิ่มลงในธุรกรรม นี่เป็นตัวเลือกที่พบบ่อยที่สุด |
| Propagation_supports | รองรับธุรกรรมปัจจุบันและหากไม่มีธุรกรรมจะถูกดำเนินการในลักษณะที่ไม่ใช่การทำธุรกรรม |
| propagation_mandatory | ใช้ธุรกรรมปัจจุบันและโยนข้อยกเว้นหากไม่มีธุรกรรม |
| propagation_requires_new | สร้างธุรกรรมใหม่ หากการทำธุรกรรมมีอยู่ในปัจจุบันให้ระงับธุรกรรมปัจจุบัน |
| propagation_not_supported | ดำเนินการดำเนินการในลักษณะที่ไม่ใช่การทำธุรกรรมและหากมีการทำธุรกรรมในปัจจุบันธุรกรรมปัจจุบันจะถูกระงับ |
| Propagation_never | ดำเนินการในลักษณะที่ไม่ใช่การทำธุรกรรมและโยนข้อยกเว้นหากมีการทำธุรกรรมอยู่ในปัจจุบัน |
| propagation_nested | หากมีการทำธุรกรรมอยู่ในปัจจุบันจะดำเนินการภายในธุรกรรมซ้อนกัน หากไม่มีธุรกรรมในปัจจุบันให้ดำเนินการคล้ายกับ Propagation_Required |
คำจำกัดความนั้นง่ายมากและเข้าใจง่าย ไปที่ส่วนทดสอบรหัสเพื่อตรวจสอบว่าความเข้าใจของเราถูกต้องหรือไม่
การยืนยันรหัส
รหัสในบทความนี้นำเสนอในสองชั้นในโครงสร้างสามชั้นแบบดั้งเดิมคือบริการและชั้น DAO ฤดูใบไม้ผลิมีหน้าที่รับผิดชอบในการฉีดการพึ่งพาและการจัดการธุรกรรมคำอธิบายประกอบ MyBatis เลเยอร์ DAO ถูกนำมาใช้ นอกจากนี้คุณยังสามารถใช้วิธีการโปรดใด ๆ เช่น Hibernate, JPA, JDBCTEMPLATE ฯลฯ ฐานข้อมูลใช้ฐานข้อมูล MySQL และคุณยังสามารถใช้ฐานข้อมูลที่เปิดใช้งานธุรกรรมใด ๆ ซึ่งจะไม่ส่งผลต่อผลการตรวจสอบ
ก่อนอื่นเราสร้างสองตารางในฐานข้อมูล:
user1
สร้างตาราง `user1` (` id` จำนวนเต็มที่ไม่ได้ลงนามไม่ได้เป็น null auto_increment, `name` varchar (45) ไม่ใช่ค่าเริ่มต้น null '', คีย์หลัก (` id`)) เครื่องยนต์ = innoDB;
user2
สร้างตาราง `user2` (` id` จำนวนเต็มที่ไม่ได้ลงนามไม่ได้เป็น null auto_increment, `name` varchar (45) ไม่ใช่ค่าเริ่มต้น null '', คีย์หลัก (` id`)) เครื่องยนต์ = innoDB;
จากนั้นเขียนรหัสเลเยอร์ถั่วและ DAO ที่เกี่ยวข้อง:
user1
ผู้ใช้ระดับสาธารณะ 1 {ID จำนวนเต็มส่วนตัว; ชื่อสตริงส่วนตัว; // get and set methods ถูกละไว้ ... }user2
ผู้ใช้ระดับสาธารณะ 2 {ID จำนวนเต็มส่วนตัว; ชื่อสตริงส่วนตัว; // get and set methods ถูกละไว้ ... }user1mapper
อินเตอร์เฟสสาธารณะ user1mapper {int แทรก (user1 Record); user1 SelectByPrimaryKey (ID จำนวนเต็ม); // วิธีอื่นถูกละไว้ ... }user2mapper
อินเทอร์เฟซสาธารณะ user2mapper {int แทรก (User2 Record); USER2 SELECTBYPRIMARYKEY (ID จำนวนเต็ม); // วิธีอื่นถูกละไว้ ... }ในที่สุดรหัสการตรวจสอบเฉพาะจะถูกนำมาใช้โดยเลเยอร์บริการและเราจะแสดงรายการในสถานการณ์ต่อไปนี้
1. propagation_required
เราเพิ่ม Propagation.REQUIRED แอตทริบิวต์ที่ต้องการในวิธีการที่สอดคล้องกันของ User1Service และ User2Service
วิธีการ user1Service:
@ServicePublic คลาส User1ServiceImpl ใช้ user1Service {// ละเว้นอื่น ๆ ... @Override @TransActional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) เป็นโมฆะสาธารณะ -วิธีการ USER2Service:
@ServicePublic คลาส User2ServiceImpl ใช้ user2Service {// ละเว้นอื่น ๆ ... @Override @TransActional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) เป็นโมฆะสาธารณะ } @Override @TransActional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) โมฆะสาธารณะ addRequiredException (ผู้ใช้ 2 ผู้ใช้) {user2mapper.insert (ผู้ใช้); โยน runtimeException ใหม่ (); - 1.1 ฉาก 1
วิธีการใช้งานอุปกรณ์ต่อพ่วงสถานการณ์นี้ไม่เปิดใช้งานการทำธุรกรรม
วิธีการตรวจสอบ 1:
@Override โมฆะสาธารณะ NotTransaction_exception_required_required () {user1 user1 = ใหม่ user1 (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.addRequired (user2); โยน runtimeException ใหม่ (); -วิธีการตรวจสอบ 2:
@Override โมฆะสาธารณะ NotTransaction_required_required_exception () {user1 user1 = user1 ใหม่ (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.AdDrequiredException (user2); -ดำเนินการตรวจสอบแยกกันและผลลัพธ์:
การวิเคราะห์ผลลัพธ์ของวิธีการตรวจสอบฐานข้อมูลหมายเลขซีเรียล
| วิธีการตรวจสอบหมายเลขซีเรียล | ผลลัพธ์ฐานข้อมูล | การวิเคราะห์ผลลัพธ์ |
|---|---|---|
| 1 | "Zhang San" และ "Li Si" ทั้งคู่แทรก | วิธีการต่อพ่วงไม่ได้เริ่มการทำธุรกรรมและการแทรกของวิธี "จางซาน" และ "Li Si" ทำงานอย่างอิสระในการทำธุรกรรมของตนเอง วิธีอุปกรณ์ต่อพ่วงที่ผิดปกติไม่ส่งผลกระทบต่อการแทรกภายในของวิธีการ "จางซาน" และ "Li Si" |
| 2 | "Zhang San" ถูกแทรก แต่ไม่ได้แทรก "Li Si" | วิธีการต่อพ่วงไม่มีการทำธุรกรรมและวิธีการแทรก "จางซาน" และ "หลี่ศรี" ทั้งคู่ทำงานอย่างอิสระในการทำธุรกรรมของตัวเองดังนั้นวิธีการแทรก "Li Si" จะย้อนกลับวิธี "Li Si" และการแทรก "Zhang San" จะไม่ได้รับผลกระทบ |
สรุป: ด้วยวิธีการทั้งสองนี้เราพิสูจน์ได้ว่าวิธีการภายในที่แก้ไขโดยการแพร่กระจายจะต้องเปิดธุรกรรมของตัวเองใหม่เมื่อวิธีการต่อพ่วงไม่ได้เปิดการทำธุรกรรมและธุรกรรมที่เปิดนั้นเป็นอิสระจากกันและไม่รบกวนกันและกัน
1.2 ฉาก 2
วิธีการต่อพ่วงเริ่มต้นการทำธุรกรรมซึ่งเป็นสถานการณ์ที่มีอัตราการใช้งานค่อนข้างสูง
วิธีการตรวจสอบ 1:
@Override @TransActional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) โมฆะสาธารณะธุรกรรม _Exception_Required_Required () {user1 user1 = user 1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.addRequired (user2); โยน runtimeException ใหม่ (); -วิธีการตรวจสอบ 2:
@Override @Transactional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) โมฆะสาธารณะธุรกรรม _Required_required_exception () {user1 user1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.AdDrequiredException (user2); -วิธีการตรวจสอบ 3:
@Transactional @Override โมฆะสาธารณะ transaction_required_required_exception_try () {user1 user1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); ลอง {user2Service.AdDrequiredException (user2); } catch (exception e) {system.out.println ("วิธีการย้อนกลับ"); -ดำเนินการตรวจสอบแยกกันและผลลัพธ์:
| วิธีการตรวจสอบหมายเลขซีเรียล | ผลลัพธ์ฐานข้อมูล | การวิเคราะห์ผลลัพธ์ |
|---|---|---|
| 1 | "Zhang San" และ "Li Si" ไม่ได้แทรก | วิธีการต่อพ่วงเริ่มต้นการทำธุรกรรมวิธีการภายในเข้าร่วมการทำธุรกรรมวิธีการต่อพ่วงวิธีการต่อพ่วงจะย้อนกลับและวิธีการภายในก็ต้องย้อนกลับ |
| 2 | "Zhang San" และ "Li Si" ไม่ได้แทรก | วิธีการต่อพ่วงจะเปิดการทำธุรกรรมวิธีการภายในเพิ่มธุรกรรมวิธีการต่อพ่วงวิธีการภายในจะทำการย้อนกลับข้อยกเว้นและวิธีการต่อพ่วงรับรู้ข้อยกเว้นทำให้การทำธุรกรรมโดยรวมกลับมาอีกครั้ง |
| 3 | "Zhang San" และ "Li Si" ไม่ได้แทรก | วิธีการต่อพ่วงจะเปิดการทำธุรกรรมวิธีการภายในเข้าร่วมการทำธุรกรรมวิธีการต่อพ่วงและวิธีการภายในจะทำการย้อนกลับข้อยกเว้น แม้ว่าวิธีการที่ถูกจับและไม่ได้รับการรับรู้โดยวิธีการต่อพ่วงการทำธุรกรรมทั้งหมดยังคงย้อนกลับไป |
สรุป: ผลการทดลองข้างต้นแสดงให้เห็นว่าเมื่อวิธีการเปิดการทำธุรกรรมวิธีการภายในที่แก้ไขโดย Propagation.REQUIRED จะต้องเพิ่มการทำธุรกรรมของวิธีการต่อพ่วง วิธีการภายในทั้งหมดและวิธีการต่อพ่วงที่แก้ไขโดย Propagation.REQUIRED ต้องการเป็นของธุรกรรมเดียวกัน ตราบใดที่วิธีการหนึ่งย้อนกลับการทำธุรกรรมทั้งหมดจะถูกย้อนกลับ
2.propagation_requires_new
เราเพิ่มแอตทริบิวต์ Propagation.REQUIRES_NEW ในวิธีการที่สอดคล้องกันของ user1Service และ user2Service
วิธีการ user1Service:
@ServicePublic คลาส user1ServiceImpl ใช้ user1Service {// ละเว้นอื่น ๆ ... @Override @Transactional (การแพร่กระจาย = การแพร่กระจาย. requires_new) โมฆะสาธารณะ addRequiresNew (ผู้ใช้ 1 ผู้ใช้) {user1Mapper.Insert (ผู้ใช้); } @Override @TransActional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) โมฆะสาธารณะ addRequired (ผู้ใช้ 1 ผู้ใช้) {user1mapper.insert (ผู้ใช้); -วิธีการ USER2Service:
@ServicePublic คลาส User2ServiceImpl ใช้ user2Service {// ละเว้นอื่น ๆ ... @Override @Transactional (การแพร่กระจาย = การแพร่กระจาย. requires_new) โมฆะสาธารณะ addrequiresNew (ผู้ใช้ 2 ผู้ใช้) {user2mapper.insert (ผู้ใช้); } @Override @Transactional (การแพร่กระจาย = การแพร่กระจาย. requires_new) โมฆะสาธารณะ addrequiresNewexception (ผู้ใช้ 2 ผู้ใช้) {user2mapper.insert (ผู้ใช้); โยน runtimeException ใหม่ (); - 2.1 ฉาก 1
วิธีการต่อพ่วงไม่ได้เปิดใช้งานการทำธุรกรรม
วิธีการตรวจสอบ 1:
@Override โมฆะสาธารณะ NotTransaction_exception_requiresNew_RequiresNew () {user1 user1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequiresNew (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.AdDrequiresNew (user2); โยน runtimeException ใหม่ (); -วิธีการตรวจสอบ 2:
@Override โมฆะสาธารณะ NotTransaction_RequiresNew_RequiresNew_Exception () {user1 user1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequiresNew (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.AdDrequiresNewException (user2); -ดำเนินการตรวจสอบแยกกันและผลลัพธ์:
| วิธีการตรวจสอบหมายเลขซีเรียล | ผลลัพธ์ฐานข้อมูล | การวิเคราะห์ผลลัพธ์ |
|---|---|---|
| 1 | "Zhang San" ถูกแทรกและแทรก "Li Si" | วิธีการต่อพ่วงไม่มีธุรกรรม การแทรกของวิธีการ "จางซาน" และ "Li Si" ดำเนินการอย่างอิสระในการทำธุรกรรมของตนเอง การย้อนกลับข้อยกเว้นของวิธีการต่อพ่วงจะไม่ส่งผลกระทบต่อวิธีการภายใน |
| 2 | "Zhang San" ถูกแทรก "Li Si" ไม่ได้แทรก | วิธีการต่อพ่วงไม่ได้เริ่มการทำธุรกรรม การแทรกของวิธี "จางซาน" และการแทรกของวิธี "Li Si" เริ่มการทำธุรกรรมของตนเองตามลำดับ การแทรกของวิธีการ "Li Si" ส่งผลต่อการย้อนกลับข้อยกเว้นและการทำธุรกรรมอื่น ๆ จะไม่ได้รับผลกระทบ |
สรุป: ด้วยวิธีการทั้งสองนี้เราพิสูจน์ว่าวิธีการภายในที่แก้ไขโดย Propagation.REQUIRES_NEW จะเริ่มการทำธุรกรรมของตัวเองใหม่และธุรกรรมที่เปิดนั้นเป็นอิสระจากกันและไม่รบกวนกันและกัน
2.2 ฉาก 2
วิธีการต่อพ่วงเริ่มการทำธุรกรรม
วิธีการตรวจสอบ 1:
@Override @Transactional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) โมฆะสาธารณะธุรกรรม _Exception_Required_requiresNew_RequiresNew () {user1 user1 user1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.AdDrequiresNew (user2); user2 user3 = ใหม่ user2 (); user3.setName ("Wang Wu"); user2Service.addrequiresNew (USER3); โยน runtimeException ใหม่ (); -วิธีการตรวจสอบ 2:
@Override @Transactional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ) โมฆะสาธารณะธุรกรรม _Required_requiresNew_RequiresNew_Exception () {user1 user1 user1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.AdDrequiresNew (user2); user2 user3 = ใหม่ user2 (); user3.setName ("Wang Wu"); user2Service.AdDrequiresNewException (user3); -วิธีการตรวจสอบ 3:
@Override @TransActional (การแพร่กระจาย = การแพร่กระจายต้องการ) โมฆะสาธารณะธุรกรรม _Required_requiresNew_RequiresNew_Exception_Try () {user1 user1 = ผู้ใช้ใหม่ 1 (); user1.setName ("จางซาน"); user1service.addrequired (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.AdDrequiresNew (user2); user2 user3 = ใหม่ user2 (); user3.setName ("Wang Wu"); ลอง {user2Service.AdDrequiresNewException (user3); } catch (exception e) {system.out.println ("Rollingback"); -ดำเนินการตรวจสอบแยกกันและผลลัพธ์:
| วิธีการตรวจสอบหมายเลขซีเรียล | ผลลัพธ์ฐานข้อมูล | การวิเคราะห์ผลลัพธ์ |
|---|---|---|
| 1 | "จางซาน" ไม่ได้แทรกไว้ "หลี่ศรี" ถูกแทรกและแทรก "วังวู" | วิธีการต่อพ่วงเริ่มต้นการทำธุรกรรมแทรกการทำธุรกรรมของวิธี "จางซาน" และวิธีการต่อพ่วงให้แทรกวิธี "Li Si" และวิธี "Wang Wu" ตามลำดับในธุรกรรมที่สร้างขึ้นใหม่ วิธีการต่อพ่วงจะมีข้อยกเว้นและหมุนธุรกรรมเดียวกับวิธีการต่อพ่วงดังนั้นวิธีการแทรกวิธี "จางซาน" จะย้อนกลับ |
| 2 | "จางซาน" ไม่ได้แทรก "หลี่ศรี" ถูกแทรกและ "วังวู" ไม่ได้แทรก | วิธีการต่อพ่วงเริ่มการทำธุรกรรมแทรกการทำธุรกรรมของวิธี "จางซาน" และวิธีการต่อพ่วงให้แทรกวิธี "Li Si" และวิธี "Wang Wu" ในการทำธุรกรรมใหม่อิสระ เมื่อแทรกวิธี "วังวู" การทำธุรกรรมที่แทรกลงในวิธี "วังวู" จะถูกย้อนกลับไป ข้อยกเว้นยังคงถูกโยนทิ้งและรับรู้ด้วยวิธีการต่อพ่วง การทำธุรกรรมของวิธีการต่อพ่วงก็ถูกย้อนกลับไปด้วยดังนั้นวิธี "จางซาน" ก็ถูกย้อนกลับไป |
| 3 | "Zhang San" ถูกแทรก "Li Si" แทรกไว้และไม่ได้แทรก "Wang Wu" | วิธีการต่อพ่วงเริ่มการทำธุรกรรมแทรกการทำธุรกรรมของวิธี "จางซาน" และวิธีการต่อพ่วงให้แทรกวิธี "Li Si" และวิธี "Wang Wu" ในการทำธุรกรรมใหม่อิสระ วิธีการ "วังวู" ถูกแทรกและธุรกรรมที่แทรกวิธี "วังวู" ถูกย้อนกลับไป ข้อยกเว้นถูกจับได้และจะไม่รับรู้ด้วยวิธีการต่อพ่วง การทำธุรกรรมของวิธีการต่อพ่วงไม่ได้ย้อนกลับไปดังนั้นการแทรกของวิธี "จางซาน" จะถูกแทรกสำเร็จ |
สรุป: เมื่อวิธีการต่อพ่วงเปิดการทำธุรกรรมวิธีการภายในที่แก้ไขโดย Propagation.REQUIRES_NEW จะยังคงเปิดธุรกรรมอิสระแยกกันและยังเป็นอิสระจากการทำธุรกรรมวิธีการภายนอก วิธีการภายในวิธีการภายในและการทำธุรกรรมวิธีการภายนอกนั้นเป็นอิสระจากกันและไม่รบกวนกันและกัน
3. propagation_nested
เราเพิ่ม Propagation.NESTED แอตทริบิวต์ที่ถูกทอดทิ้งไปยังวิธีการที่สอดคล้องกันของ User1Service และ User2Service
วิธีการ user1Service:
@ServicePublic คลาส User1ServiceImpl ใช้ user1Service {// ละเว้นอื่น ๆ ... @Override @TransActional (การแพร่กระจาย = การแพร่กระจาย. nested) โมฆะสาธารณะ addnested (ผู้ใช้ 1 ผู้ใช้) {user1mapper.insert (ผู้ใช้); -วิธีการ USER2Service:
@ServicePublic คลาส User2ServiceImpl ใช้ user2Service {// ละเว้นอื่น ๆ ... @Override @TransActional (การแพร่กระจาย = การแพร่กระจาย. nested) โมฆะสาธารณะ addnested (ผู้ใช้ 2 ผู้ใช้) {user2mapper.insert (ผู้ใช้); } @Override @TransActional (การแพร่กระจาย = การแพร่กระจายไปแล้ว) โมฆะสาธารณะ AddNestedException (ผู้ใช้ 2 ผู้ใช้) {user2mapper.insert (ผู้ใช้); โยน runtimeException ใหม่ (); - 3.1 ฉาก 1
วิธีการใช้งานอุปกรณ์ต่อพ่วงสถานการณ์นี้ไม่เปิดใช้งานการทำธุรกรรม
วิธีการตรวจสอบ 1:
@Override โมฆะสาธารณะ NotTransaction_exception_nested_nested () {user1 user1 = user1 ใหม่ (); user1.setName ("จางซาน"); user1service.addnested (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.Addnested (user2); โยน runtimeException ใหม่ (); -วิธีการตรวจสอบ 2:
@Override โมฆะสาธารณะ NotTransaction_nested_nested_exception () {user1 user1 = user1 ใหม่ (); user1.setName ("จางซาน"); user1service.addnested (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.addnestedException (user2); -ดำเนินการตรวจสอบแยกกันและผลลัพธ์:
| วิธีการตรวจสอบหมายเลขซีเรียล | ผลลัพธ์ฐานข้อมูล | การวิเคราะห์ผลลัพธ์ |
|---|---|---|
| 1 | "Zhang San" และ "Li Si" ทั้งคู่แทรก | วิธีการต่อพ่วงไม่ได้เริ่มการทำธุรกรรมและการแทรกของวิธี "จางซาน" และ "Li Si" ทำงานอย่างอิสระในการทำธุรกรรมของตนเอง วิธีอุปกรณ์ต่อพ่วงที่ผิดปกติไม่ส่งผลกระทบต่อการแทรกภายในของวิธีการ "จางซาน" และ "Li Si" |
| 2 | "Zhang San" ถูกแทรก แต่ไม่ได้แทรก "Li Si" | วิธีการต่อพ่วงไม่มีการทำธุรกรรมและวิธีการแทรก "จางซาน" และ "หลี่ศรี" ทั้งคู่ทำงานอย่างอิสระในการทำธุรกรรมของตัวเองดังนั้นวิธีการแทรก "Li Si" จะย้อนกลับวิธี "Li Si" และการแทรก "Zhang San" จะไม่ได้รับผลกระทบ |
สรุป: ด้วยวิธีการทั้งสองนี้เราพิสูจน์ได้ว่า Propagation.NESTED และ Propagation.REQUIRED มีฟังก์ชั่นเดียวกันเมื่อวิธีการต่อพ่วงไม่ได้เปิดการทำธุรกรรม วิธีการภายในที่ได้รับการแก้ไขจะเริ่มต้นการทำธุรกรรมของตนเองอีกครั้งและธุรกรรมที่เปิดนั้นเป็นอิสระจากกันและไม่รบกวนกันและกัน
3.2 ฉาก 2
วิธีการต่อพ่วงเริ่มการทำธุรกรรม
วิธีการตรวจสอบ 1:
@Transactional @Override โมฆะสาธารณะธุรกรรม _exception_nested_nested () {user1 user1 = ใหม่ user1 (); user1.setName ("จางซาน"); user1service.addnested (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.Addnested (user2); โยน runtimeException ใหม่ (); -วิธีการตรวจสอบ 2:
@Transactional @Override โมฆะสาธารณะธุรกรรม _nested_nested_exception () {user1 user1 = ใหม่ user1 (); user1.setName ("จางซาน"); user1service.addnested (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); user2Service.addnestedException (user2); -วิธีการตรวจสอบ 3:
@Transactional @Override โมฆะสาธารณะธุรกรรม _nested_nested_exception_try () {user1 user1 = user1 ใหม่ (); user1.setName ("จางซาน"); user1service.addnested (user1); user2 user2 = ใหม่ user2 (); user2.setName ("Li Si"); ลอง {user2Service.addnestedException (USER2); } catch (exception e) {system.out.println ("วิธีการย้อนกลับ"); -ดำเนินการตรวจสอบแยกกันและผลลัพธ์:
| วิธีการตรวจสอบหมายเลขซีเรียล | ผลลัพธ์ฐานข้อมูล | การวิเคราะห์ผลลัพธ์ |
|---|---|---|
| 1 | "Zhang San" และ "Li Si" ไม่ได้แทรก | วิธีการต่อพ่วงเริ่มต้นการทำธุรกรรมและการทำธุรกรรมภายในเป็นการทำธุรกรรมย่อยของธุรกรรมอุปกรณ์ต่อพ่วง วิธีการรอบข้างจะย้อนกลับและวิธีการภายในก็ต้องย้อนกลับ |
| 2 | "Zhang San" และ "Li Si" ไม่ได้แทรก | วิธีการต่อพ่วงเริ่มต้นการทำธุรกรรมและการทำธุรกรรมภายในเป็นการทำธุรกรรมย่อยของธุรกรรมอุปกรณ์ต่อพ่วง วิธีการภายในทำให้เกิดการย้อนกลับข้อยกเว้นและวิธีการต่อพ่วงรับรู้ข้อยกเว้นทำให้การทำธุรกรรมโดยรวมกลับมาอีกครั้ง |
| 3 | "Zhang San" ถูกแทรกและ "Li Si" ไม่ได้แทรก | วิธีการต่อพ่วงเริ่มต้นการทำธุรกรรมและการทำธุรกรรมภายในเป็นการทำธุรกรรมย่อยของธุรกรรมอุปกรณ์ต่อพ่วง แทรกวิธีการภายใน "จางซาน" เพื่อโยนข้อยกเว้นและการทำธุรกรรมเด็กสามารถย้อนกลับได้แยกกัน |
บทสรุป: ผลการทดสอบข้างต้นแสดงให้เห็นว่าเมื่อวิธีการเปิดการทำธุรกรรมวิธีการภายในที่แก้ไขโดย Propagation.NESTED เป็นของการทำธุรกรรมย่อยของการทำธุรกรรมภายนอก การทำธุรกรรมหลักต่อพ่วงจะหมุนกลับและการทำธุรกรรมย่อยจะต้องย้อนกลับ การทำธุรกรรมย่อยภายในสามารถย้อนกลับแยกกันได้โดยไม่ส่งผลกระทบต่อธุรกรรมหลักและการทำธุรกรรมย่อยอื่น ๆ
4. ความคล้ายคลึงกันและความคล้ายคลึงกันของจำเป็นต้องใช้ _new, ซ้อนกัน
จากการเปรียบเทียบ "1.2 scene 2" และ "3.2 scene 2" เราจะเห็น:
วิธีการภายในที่แก้ไขโดยซ้อนกันและจำเป็นต้องใช้ทั้งสองวิธีการทำธุรกรรมต่อพ่วง หากวิธีการต่อพ่วงมีข้อยกเว้นการทำธุรกรรมของทั้งสองวิธีจะถูกย้อนกลับ อย่างไรก็ตามจำเป็นต้องมีการเข้าร่วมการทำธุรกรรมวิธีการต่อพ่วงดังนั้นจึงเป็นของการทำธุรกรรมเดียวกันกับการทำธุรกรรมอุปกรณ์ต่อพ่วง เมื่อการทำธุรกรรมที่จำเป็นต้องมีข้อยกเว้นและย้อนกลับไปแล้วการทำธุรกรรมวิธีการต่อพ่วงจะถูกย้อนกลับไป ซ้อนกันคือการทำธุรกรรมย่อยของวิธีการต่อพ่วงและมีจุดบันทึกแยกต่างหากดังนั้นวิธีที่ซ้อนกันจึงมีข้อยกเว้นและถูกย้อนกลับซึ่งจะไม่ส่งผลกระทบต่อการทำธุรกรรมของวิธีการต่อพ่วง
จากการเปรียบเทียบ "2.2 ฉาก 2" และ "3.2 ฉาก 2" เราจะเห็น:
ทั้งที่ซ้อนกันและต้องการ _New สามารถย้อนกลับการทำธุรกรรมวิธีการภายในโดยไม่ส่งผลกระทบต่อการทำธุรกรรมวิธีการต่อพ่วง อย่างไรก็ตามเนื่องจากซ้อนกันเป็นธุรกรรมที่ซ้อนกันหลังจากวิธีการต่อพ่วงกลับมาแล้วการทำธุรกรรมย่อยที่เป็นวิธีการทำธุรกรรมรอบนอกจะถูกย้อนกลับไป ต้องการ _New ถูกนำไปใช้โดยการเปิดธุรกรรมใหม่ ธุรกรรมภายในและธุรกรรมอุปกรณ์ต่อพ่วงเป็นสองธุรกรรม การย้อนกลับการทำธุรกรรมรอบนอกจะไม่ส่งผลกระทบต่อการทำธุรกรรมภายใน
5. พฤติกรรมการแพร่กระจายการทำธุรกรรมอื่น ๆ
ในมุมมองของปัญหาความยาวของบทความการทดสอบพฤติกรรมการแพร่กระจายการทำธุรกรรมอื่น ๆ จะไม่ได้รับการอธิบายที่นี่ ผู้อ่านที่สนใจสามารถค้นหารหัสทดสอบที่เกี่ยวข้องและคำอธิบายผลลัพธ์ในซอร์สโค้ด พอร์ทัล: https: //github.com/tmtse/tran ...
กรณีการใช้แบบจำลอง
หลังจากแนะนำพฤติกรรมการสื่อสารการทำธุรกรรมมากมายเราจะนำไปใช้กับงานจริงของเราได้อย่างไร? ให้ฉันยกตัวอย่างให้คุณ:
สมมติว่าเรามีวิธีการลงทะเบียนซึ่งวิธีการเพิ่มจุดที่เรียกว่า หากเราต้องการเพิ่มคะแนนเพื่อไม่ส่งผลกระทบต่อกระบวนการลงทะเบียน (นั่นคือการย้อนกลับล้มเหลวในการเพิ่มคะแนนไม่สามารถทำให้วิธีการลงทะเบียนย้อนกลับได้ด้วย) เราจะเขียนสิ่งนี้:
@Service ชั้นเรียนสาธารณะ UserserViceImpl ดำเนินการ UserserVice {@Transactional Public Void register (ผู้ใช้ผู้ใช้) {ลอง {membershippointservice.addpoint (จุดจุด); } catch (Exception e) {// omit ... } // omit ... } // omit ... } นอกจากนี้เรายังกำหนดว่าความล้มเหลวในการลงทะเบียนจะส่งผลกระทบต่อวิธีการ addPoint() (วิธีการลงทะเบียนการย้อนกลับยังต้องมีการย้อนกลับ) ดังนั้นวิธี addPoint() จะต้องดำเนินการเช่นนี้:
@Service คลาสสาธารณะคลาสสมาชิก HIPPOINTSERVICICEIMPL ดำเนินการ MEBERSHIPPOINTSERVICE {@TransActional (การแพร่กระจาย = การแพร่กระจาย) โมฆะสาธารณะ addpoint (จุดจุด) {ลอง {recordService.addrecord (บันทึก); } catch (Exception e) {// omit ... } // omit ... } // omit ... } เราสังเกตเห็นว่าเมธอด addRecord() addPoint() ซึ่งใช้ในการบันทึกบันทึก การดำเนินการของเขามีดังนี้:
@Service ชั้นเรียนสาธารณะ RecordServiceImpl ใช้ RecordService {@TransActional (การแพร่กระจาย = การแพร่กระจาย NONT_SUPPORTED) โมฆะสาธารณะ addRecord (บันทึก) {// omit ... } // ละเว้น ... }} เราสังเกตเห็น propagation = Propagation.NOT_SUPPORTED ในวิธี addRecord() addRecord() addRecord() เองและวิธี addRecord() addPoint() addPoint() จะไม่ส่งผลต่อ
จากตัวอย่างนี้ฉันเชื่อว่าทุกคนมีความเข้าใจที่เข้าใจง่ายมากขึ้นเกี่ยวกับการใช้พฤติกรรมการสื่อสารการทำธุรกรรม การรวมกันของคุณลักษณะต่าง ๆ สามารถทำให้การดำเนินธุรกิจของเรามีความยืดหยุ่นและหลากหลายมากขึ้น
สรุปแล้ว
ผ่านการแนะนำข้างต้นฉันเชื่อว่าทุกคนมีความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับพฤติกรรมการสื่อสารการทำธุรกรรมในฤดูใบไม้ผลิและฉันหวังว่างานพัฒนาประจำวันของคุณจะเป็นประโยชน์
สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่าเนื้อหาของบทความนี้จะมีค่าอ้างอิงบางอย่างสำหรับการศึกษาหรือที่ทำงานของทุกคน หากคุณมีคำถามใด ๆ คุณสามารถฝากข้อความไว้เพื่อสื่อสาร ขอบคุณสำหรับการสนับสนุน Wulin.com