1. عندما يتم استخدام mybatis بمفرده ، استخدم SQLSession للتعامل مع المعاملات:
الطبقة العامة myBatistxtest {private static sqlsessionfactory sqlsessionFactory ؛ قارئ قارئ ثابت خاص ؛ beboReClass public static void setupBebeForeClass () يلقي استثناء {try {reader = resources.getResourCeasReader ("configuration.xml") ؛ sqlsessionFactory = جديد sqlsessionfactorybuilder (). build (reader) ؛ } أخيرًا {if (reader! = null) {reader.close () ؛ }}} test public void updateUseRtxTest () {sqlsession session = sqlsessionfactory.opensession (false) ؛ // افتح الجلسة وتبدأ المعاملة جرب {iusermapper mapper = session.getMapper (iusermapper.class) ؛ مستخدم المستخدم = مستخدم جديد (9 ، "اختبار معاملة") ؛ int effectedCount = mapper.updateuser (user) ؛ // لم يتم تنفيذ بيان الالتزام بسبب مستخدم مستخدم الاستثناء اللاحق = مستخدم جديد (10 ، "Test Transaction بشكل مستمر") ؛ int effectedCount2 = mapper.updateuser (user2) ؛ // لا يتم تنفيذ بيان الالتزام int i = 2/0 بسبب الاستثناء اللاحق ؛ // يتم تشغيل استثناء وقت التشغيل session.commit () ؛ // تقديم الجلسة ، أي أن المعاملة الالتزام} أخيرًا {session.close () ؛ // أغلق الجلسة وإصدار موارد}}}
2. بعد الاندماج مع الربيع ، استخدم إدارة معاملات الربيع:
أحد الأسباب الرئيسية لاستخدام MyBatis-Spring هو أنه يسمح لـ MyBatis بالمشاركة في إدارة المعاملات في Spring. بدلاً من إنشاء مدير معاملات محدد جديد لـ MyBatis ، يستخدم MyBatis-Spring جهاز DataSourCetransactionManager الموجود في الربيع.
بمجرد تكوين DataSourCeTransActionManager ، يمكنك تكوين المعاملات في الربيع كما تفعل عادة. يتم دعم التعليق التوضيحي transactional وتكوين نمط AOP. أثناء معالجة المعاملات ، سيتم إنشاء كائن SQLSession منفصل واستخدامه. عند اكتمال المعاملة ، سيتم ارتكاب هذه الجلسة أو تراجعها بالطريقة المناسبة.
بمجرد إنشاء المعاملة ، ستقوم MyBatis-Spring بإدارة المعاملات بشفافية. ليست هناك حاجة للحصول على رمز إضافي في DAO أو فئة الخدمة.
1. التكوين القياسي
لتمكين معالجة معاملات Spring ، ما عليك سوى إنشاء كائن DataSourCetransActionManager في ملف تكوين XML الخاص بـ Spring:
<bean id = "TransactionManager"> <property name = "datasource" ref = "datasource"/> </bean>
يمكن أن تكون مصدر البيانات المحدد عمومًا أي بيانات بيانات JDBC التي تستخدمها Spring. ويشمل ذلك تجمع الاتصال و DataSource تم الحصول عليه من خلال البحث JNDI.
لاحظ أن مصدر البيانات المحدد لمدير المعاملات يجب أن يكون نفس مصدر البيانات الذي يتم استخدامه لإنشاء SQLSessionFactoryBean ، وإلا فلن يعمل مدير المعاملات.
2. معاملات إدارة الحاويات
إذا كنت تستخدم حاوية JEE وتريد أن تشارك Spring في معاملات إدارة الحاويات ، فيجب تكوين Spring باستخدام JTatransactionManager أو فئة فرعية محددة من قبل الحاوية. الطريقة الأكثر ملاءمة للقيام بذلك هي استخدام مساحة اسم معاملة الربيع:
<TX: JTA-Transaction-Manager/>
في هذا التكوين ، سيكون MyBatis هو نفسه موارد معاملات الربيع الأخرى التي تم تكوينها بواسطة معاملات إدارة الحاويات. سيستخدم Spring تلقائيًا أي معاملات حاوية موجودة ، مع إرفاق SQLSession به. إذا لم يتم بدء المعاملة ، أو إذا كانت المعاملة مطلوبة ، فستمكّن Spring حاوية جديدة من إدارة المعاملات.
لاحظ أنه إذا كنت ترغب في إدارة المعاملات باستخدام الحاويات وليس إدارة معاملات Spring ، فيجب عليك تكوين SQLSessionFactoryBean لاستخدام MABATIS MAGNEDTRANSACTOATORE الأساسي بدلاً من أي مدير معاملات الربيع الأخرى:
<bean id = "sqlsessionfactory"> <property name = "datasource" ref = "datasource"/> <property name = "TransactionFactoryClass
3. إدارة المعاملات البرمجية
يوفر MyBatis 'SQLSession طريقة محددة للتعامل مع المعاملات البرمجية. ولكن عند استخدام MyBatis-Spring ، سيتم حقن الفول باستخدام SQLSession أو Mapper الذي يديره الربيع. وهذا يعني أن الربيع عادة ما يتعامل مع المعاملات. لا يمكنك استدعاء أساليب sqlsession.commit () ، sqlsession.rollback () ، أو sqlsession.close () على sqlsession التي تديرها نابض. إذا قمت بذلك ، فسيتم إلقاؤه غير مدعوم. لاحظ أنه لا يمكن الوصول إلى هذه الأساليب عند استخدام MAPPERS المحقونة. بغض النظر عما إذا كان يتم تعيين الاتصال على التلقائي أم لا ، سيتم تنفيذ طريقة بيانات SQLSession أو أي مكالمة إلى طريقة Mapper خارج معاملة الربيع تلقائيًا. فيما يلي مثال على معاملة البرمجة:
defaultTransActionDefinition def = new DefaultTransActionDefinition () ؛ def.setPropagationBehavior (TransactionDefinition.propagation_required) ؛ المعاملة status = txmanager.getTransaction (def) ؛ حاول {usermapper.insertuser (user) ؛ } catch (myException ex) {throw ex ؛ } txmanager.commit (الحالة) ؛4.@طريقة المعاملات:
قم بإنشاء ملف Beans-da-tx.xml ضمن ClassPath وأضف تكوين المعاملات استنادًا إلى Beans-da.xml (Series V):
<!-مدير المعاملات-> <bean id = "txmanager"> <property name = "dataSource" ref = "datasource" /> </bean> <!-سائق التعليقات التوضيحية للمعاملات ، والفئات والأساليب المحددة @transactional ستكون المعاملات-> <tx: anotation-driven-manager = "txmanager" />
فئة الخدمة:
service ("userverservice") فئة عامة usterviservice {autowired iusermapper mapper ؛ Public Int BatchupDateusersWhenException () {// user user User = مستخدم جديد (9 ، "قبل الاستثناء") ؛ int effectedCount = mapper.updateuser (user) ؛ // تنفيذ مستخدم مستخدم ناجح = مستخدم جديد (10 ، "بعد الاستثناء") ؛ int i = 1/0 ؛ // رمي وقت التشغيل استثناء int intedcount2 = mapper.updateuser (user2) ؛ // لم يتم تنفيذها إذا (effectedCount == 1 && OffectedCount2 == 1) {return 1 ؛ } العودة 0 ؛ } TransActional public int txupdateuserswhenexception () {// user user user = new user (9 ، "قبل الاستثناء") ؛ int effectedCount = mapper.updateuser (user) ؛ // التراجع بسبب الاستثناء اللاحق user user2 = مستخدم جديد (10 ، "بعد استثناء") ؛ int i = 1/0 ؛ // رمي استثناء وقت التشغيل وتراجع المعاملة int intedcount2 = mapPPer.upDateuser (user2) ؛ // لم يتم تنفيذها إذا (effectedCount == 1 && OffectedCount2 == 1) {return 1 ؛ } العودة 0 ؛ }}في فئة الاختبار:
Runwith (SpringJunit4ClassRunner.Class) contextConfiguration (مواقع = {"classpath: beans-da-tx.xml"}) الفئة العامة springintegrateStest {resource orperService userservice ؛ test public void updateUsexceptionTest () {userService.BatchUpDateUsersWhenException () ؛ } test public void txupDateSexceptionTest () {userservice.txupdateuserswhenexception () ؛ }}
5. طريقة المعاملات
أضف في Beans-da-tx.xml:
<bean id = "txtemplate"> <constructor-arg type = "org.springframework.transaction.platformtransactionManager" ref = "TransactionManager" /> </bean>
انضم إلى فئة Userveservice:
@autowired (مطلوب = خطأ) TransactionTemplate txtemplate ؛ public int txupdateUsershenexceptionViatStemplate () {int retval = txtemplate.execute (New TransactionCallback <integer> () {Override integer doInTransactaction (intactactions) user user 2 = مستخدم جديد ، "بعد الاستثناء") ؛ إرجاع العودة. }أضف إلى فئة SpringIntegrateStest:
test public void updateUsersershenexceptionViatStemplateSt () {userService.txupDateUsersWhenExceptionViatStemplate () ؛ //}ملاحظة: لا يمكن استثناء الاستثناء أو RunTimeException دون رمي:
TransActional Public int txupdateuserserwhenexceptionAndCatch () {// تشغيل المعاملات ، لكن الإطار المحيطي لا يمكن أن يلتقط الاستثناء وإرساله إذا كان التنفيذ صحيحًا. جرب {user user = new user (9 ، "قبل الاستثناء") ؛ int effectedCount = mapper.updateuser (user) ؛ // كان التنفيذ ناجحًا للمستخدم 2 = مستخدم جديد (10 ، "بعد الاستثناء") ؛ int i = 1/0 ؛ // رمي وقت التشغيل استثناء int intedcount2 = mapper.updateuser (user2) ؛ // لم يتم تنفيذها إذا (effectedCount == 1 && OffectedCount2 == 1) {return 1 ؛ }} catch (استثناء e) {// يتم اكتشاف جميع الاستثناءات دون رمي eprintstacktrace () ؛ } العودة 0 ؛ }