1. เมื่อใช้ mybatis เพียงอย่างเดียวให้ใช้ sqlsession เพื่อจัดการธุรกรรม:
คลาสสาธารณะ MyBatistxtest {ส่วนตัว SQLSessionFactory SQLSessionFactory; ผู้อ่านผู้อ่านแบบคงที่ส่วนตัว @beforeclass โมฆะสาธารณะคงที่ setupbeforeclass () โยนข้อยกเว้น {ลอง {reader = resources.getResourceAsreader ("configuration.xml"); SQLSessionFactory = ใหม่ SQLSessionFactoryBuilder (). build (reader); } ในที่สุด {ถ้า (reader! = null) {reader.close (); }}} @Test โมฆะสาธารณะ updateUsTsTest () {SQLSESSION SESSION = SQLSessionFactory.OpenSession (FALSE); // เปิดเซสชันและการทำธุรกรรมเริ่มต้นลอง {iusermapper mapper = session.getMapper (iusermapper.class); ผู้ใช้ผู้ใช้ = ผู้ใช้ใหม่ (9, "การทดสอบธุรกรรม"); int extedcount = mapper.updateUser (ผู้ใช้); // คำสั่ง commit ไม่ได้ดำเนินการเนื่องจากผู้ใช้ข้อยกเว้นที่ตามมาผู้ใช้ = ผู้ใช้ใหม่ (10, "ทดสอบธุรกรรมอย่างต่อเนื่อง"); int extedcount2 = mapper.updateUser (user2); // คำสั่ง commit int i = 2/0 ไม่ได้ดำเนินการเนื่องจากข้อยกเว้นที่ตามมา; // ข้อยกเว้นรันไทม์จะถูกเรียกใช้เซสชัน commmit (); // ส่งเซสชันนั่นคือการทำธุรกรรม commit} ในที่สุด {session.close (); // ปิดเซสชันและทรัพยากรรีลีส}}}
2. หลังจากรวมเข้ากับฤดูใบไม้ผลิใช้การจัดการธุรกรรมของฤดูใบไม้ผลิ:
หนึ่งในเหตุผลหลักในการใช้ mybatis-spring คือช่วยให้ mybatis สามารถเข้าร่วมในการจัดการธุรกรรมของฤดูใบไม้ผลิ แทนที่จะสร้างตัวจัดการธุรกรรมเฉพาะใหม่สำหรับ MyBatis MyBatis-Spring ใช้ DataSourceTransactionManager ที่มีอยู่ในฤดูใบไม้ผลิ
เมื่อกำหนดค่า DataSourceTransactionManager คุณสามารถกำหนดค่าการทำธุรกรรมในฤดูใบไม้ผลิตามปกติ @Transactional คำอธิบายประกอบและการกำหนดค่าสไตล์ AOP ได้รับการสนับสนุน ในระหว่างการประมวลผลธุรกรรมจะมีการสร้างและใช้วัตถุ SQLSession แยกต่างหาก เมื่อการทำธุรกรรมเสร็จสิ้นเซสชั่นนี้จะเกิดขึ้นหรือย้อนกลับไปในวิธีที่เหมาะสม
เมื่อการทำธุรกรรมถูกสร้างขึ้น MyBatis-Spring จะจัดการธุรกรรมอย่างโปร่งใส ไม่จำเป็นต้องมีรหัสเพิ่มเติมใน DAO หรือคลาสบริการของคุณ
1. การกำหนดค่ามาตรฐาน
ในการเปิดใช้งานการประมวลผลธุรกรรมของ Spring เพียงสร้างวัตถุ DataSourceTransactionManager ในไฟล์กำหนดค่า XML ของ Spring:
<bean id = "transactionManager"> <property name = "dataSource" ref = "dataSource"/> </ebean>
แหล่งข้อมูลที่ระบุโดยทั่วไปอาจเป็นแหล่งข้อมูล JDBC ใด ๆ ที่คุณใช้ Spring ซึ่งรวมถึงพูลการเชื่อมต่อและแหล่งข้อมูลที่ได้จากการค้นหา JNDI
โปรดทราบว่าแหล่งข้อมูลที่ระบุสำหรับตัวจัดการธุรกรรมจะต้องเป็นแหล่งข้อมูลเดียวกับที่ใช้ในการสร้าง SQLSessionFactoryBean มิฉะนั้นตัวจัดการธุรกรรมจะไม่ทำงาน
2. ธุรกรรมการจัดการคอนเทนเนอร์
หากคุณใช้คอนเทนเนอร์ JEE และต้องการให้สปริงมีส่วนร่วมในการทำธุรกรรมการจัดการคอนเทนเนอร์ควรกำหนดค่าสปริงโดยใช้ JTatransactionManager หรือคลาสย่อยที่ระบุไว้ในคอนเทนเนอร์ วิธีที่สะดวกที่สุดในการทำเช่นนี้คือการใช้เนมสเปซธุรกรรมของ Spring:
<TX: JTA-Transaction-Manager/>>>
ในการกำหนดค่านี้ MyBatis จะเหมือนกับทรัพยากรธุรกรรมสปริงอื่น ๆ ที่กำหนดค่าโดยธุรกรรมการจัดการคอนเทนเนอร์ สปริงจะใช้ธุรกรรมคอนเทนเนอร์ที่มีอยู่โดยอัตโนมัติ หากการทำธุรกรรมไม่ได้เริ่มต้นหรือหากจำเป็นต้องทำธุรกรรมสปริงจะเปิดใช้งานคอนเทนเนอร์ใหม่ในการจัดการธุรกรรม
โปรดทราบว่าหากคุณต้องการจัดการธุรกรรมโดยใช้คอนเทนเนอร์ไม่ใช่การจัดการธุรกรรมของ Spring คุณต้องกำหนดค่า SQLSessionFactoryBean เพื่อใช้ MyBatis ManagedTransactionFactory พื้นฐานแทนตัวจัดการธุรกรรมสปริงอื่น ๆ :
<bean id = "sqlsessionfactory"> <property name = "dataSource" ref = "dataSource"/> <property name = "TransactionFactoryClass"> <value> org.apache.ibatis.transaction.Managed.ManagedTransactionF
3. การจัดการธุรกรรมการเขียนโปรแกรม
SQLSession ของ MyBatis มีวิธีการที่ระบุเพื่อจัดการการทำธุรกรรมแบบโปรแกรม แต่เมื่อใช้ mybatis-spring ถั่วจะถูกฉีดโดยใช้ sqlsession หรือ mapper ที่จัดการสปริง นั่นหมายถึงสปริงมักจะจัดการธุรกรรม คุณไม่สามารถโทรหา sqlsession.commit (), sqlsession.rollback () หรือ sqlsession.close () วิธีการใน SQLSession ที่จัดการกับฤดูใบไม้ผลิ หากคุณทำสิ่งนี้จะมีการโยน unsupportedoperationexception โปรดทราบว่าวิธีการเหล่านั้นไม่สามารถเข้าถึงได้เมื่อใช้แม็ปเปอร์ที่ฉีด ไม่ว่าการเชื่อมต่อจะถูกตั้งค่าเป็น AutoCommit หรือไม่การดำเนินการของวิธีการข้อมูล SQLSession หรือการโทรไปยังวิธี Mapper นอกธุรกรรมสปริงจะมีการกระทำโดยอัตโนมัติ นี่คือตัวอย่างของการทำธุรกรรมการเขียนโปรแกรม:
DefaultTransactionDefinition def = ใหม่ defaultTransactionDefinition (); def.setPropagationBehavior (transactionDefinition.propagation_required); TransactionStatus สถานะ = txManager.getTransaction (def); ลอง {usermapper.insertuser (ผู้ใช้); } catch (myexception ex) {โยน ex; } txManager.Commit (สถานะ);4.@วิธีการทำธุรกรรม:
สร้างไฟล์ Beans-da-tx.xml ภายใต้ classpath และเพิ่มการกำหนดค่าธุรกรรมตาม Beans-da.xml (series V):
<!-ตัวจัดการธุรกรรม-> <bean id = "txManager"> <property name = "dataSource" ref = "DataSource" /> </ebean> <!-ไดรเวอร์คำอธิบายประกอบการทำธุรกรรมคลาสและวิธีการที่ทำเครื่องหมาย @Transactional จะเป็นธุรกรรม- />
หมวดหมู่บริการ:
@Service ("Userservice") Public Class Userservice {@autowired iusermapper Mapper; สาธารณะ int batchUpDateUsersWheneXception () {// ผู้ใช้ที่ไม่ใช่ผู้ใช้งานที่ไม่ใช่ผู้ใช้ = ผู้ใช้ใหม่ (9, "ก่อนยกเว้น"); int extedcount = mapper.updateUser (ผู้ใช้); // ดำเนินการผู้ใช้ที่ประสบความสำเร็จผู้ใช้ 2 = ผู้ใช้ใหม่ (10, "หลังจากข้อยกเว้น"); int i = 1 /0; // โยนข้อยกเว้นรันไทม์ int extedcount2 = mapper.updateUser (user2); // ไม่ได้ดำเนินการถ้า (extedcount == 1 && effectCount2 == 1) {return 1; } return 0; } @Transactional public int txupdateUserswhenexception () {// ผู้ใช้ผู้ใช้ธุรกรรม = ผู้ใช้ใหม่ (9, "ก่อนยกเว้น"); int extedcount = mapper.updateUser (ผู้ใช้); // ย้อนกลับเนื่องจากผู้ใช้ข้อยกเว้นที่ตามมาผู้ใช้ 2 = ผู้ใช้ใหม่ (10, "หลังจากข้อยกเว้น"); int i = 1 /0; // โยนข้อยกเว้นรันไทม์และการทำธุรกรรมการย้อนกลับ int effectCount2 = mappper.updateUser (user2); // ไม่ได้ดำเนินการถ้า (extedcount == 1 && effectCount2 == 1) {return 1; } return 0; -ในคลาสทดสอบ:
@runwith (springjunit4classrunner.class) @contextconfiguration (locations = {"classpath: beans-da-tx.xml"}) คลาสสาธารณะ SpringintegratetTest {@Resource Userservice Userservice; @Test Public Void UpdateUserSexceptionTest () {UserserVice.BatchUpDateUsersWheneXception (); } @Test โมฆะสาธารณะ TXUPDATEUSSEXPECTIONTEST () {UserserVice.txUpDateUsersWheneXception (); -
5. วิธีการทำธุรกรรม Template
เพิ่มใน Beans-da-tx.xml:
<bean id = "txtemplate"> <constructor-arg type = "org.springframework.transaction.platformTransactionManager" ref = "TransactionManager" /> </ebean>
เข้าร่วมในคลาส Userservice:
@autowired (จำเป็น = false) transactionTemplate txtemplate; public int txupdateUserswenexceptionViatxtemplate () {int retval = txTemplate.execute (TransactionCallback ใหม่ <จำนวนเต็ม> () {@Override Integer Public DoinTransaction (TransactionStatus สถานะ) ผู้ใช้ข้อยกเว้นที่ตามมา 2 = ผู้ใช้ใหม่ (10, "หลังจากนั้น"); int i = 1 /0; returnval; -เพิ่มในคลาส SpringInteGratetTest:
@Test Public Void UpdateUsersWhenExceptionViatXtEmplatetest () {userservice.txupdateUsersWhenexceptionViatxtemplate (); -หมายเหตุ: ไม่สามารถจับข้อยกเว้นหรือ RuntimeException ได้โดยไม่ต้องขว้าง:
@Transactional public int txupdateUsersWheneXceptionAndCatch () {// การดำเนินการธุรกรรม แต่เฟรมเวิร์กอุปกรณ์ต่อพ่วงไม่สามารถตรวจจับข้อยกเว้นและส่งได้หากการดำเนินการถูกต้อง ลอง {user user = ผู้ใช้ใหม่ (9, "ก่อนยกเว้น"); int extedcount = mapper.updateUser (ผู้ใช้); // การดำเนินการเป็นผู้ใช้ที่ประสบความสำเร็จผู้ใช้ 2 = ผู้ใช้ใหม่ (10, "หลังจากข้อยกเว้น"); int i = 1 /0; // โยนข้อยกเว้นรันไทม์ int extedcount2 = mapper.updateUser (user2); // ไม่ได้ดำเนินการถ้า (extedcount == 1 && effectCount2 == 1) {return 1; }} catch (Exception e) {// ข้อยกเว้นทั้งหมดถูกจับโดยไม่ต้องโยน e.printstacktrace (); } return 0; -