บทความนี้ส่วนใหญ่ศึกษาเนื้อหาที่เกี่ยวข้องของกลไกการทำธุรกรรมของฤดูใบไม้ผลิดังต่อไปนี้
โดยปกติจะมีกลยุทธ์การทำธุรกรรมสองประการ: การทำธุรกรรมทั่วโลกและธุรกรรมในท้องถิ่น การทำธุรกรรมทั่วโลกสามารถขยายทรัพยากรการทำธุรกรรมหลายรายการ (เช่นแหล่งข้อมูลโดยทั่วไปฐานข้อมูลและคิวข้อความ) และมักจะต้องมีการจัดการเซิร์ฟเวอร์แอปพลิเคชัน J2EE ซึ่งต้องการการสนับสนุน JTA ของเซิร์ฟเวอร์ที่ด้านล่าง การทำธุรกรรมในท้องถิ่นเกี่ยวข้องกับเทคโนโลยีการคงอยู่ที่นำมาใช้โดยเลเยอร์พื้นฐาน หากเลเยอร์พื้นฐานใช้ JDBC โดยตรงจะต้องใช้วัตถุการเชื่อมต่อเพื่อใช้งานธุรกรรม หากใช้เทคโนโลยีการคงอยู่ของไฮเบอร์เนตคุณจะต้องใช้วัตถุเซสชันเพื่อใช้งานธุรกรรม
โดยทั่วไปกระบวนการเขียนโปรแกรมโดยใช้ธุรกรรม JTA การทำธุรกรรม JDBC และธุรกรรมไฮเบอร์เนตมีดังนี้
ดังที่เห็นได้จากรูปด้านบนโดยใช้การเขียนโปรแกรมธุรกรรมแบบดั้งเดิมรหัสโปรแกรมจะต้องควบคู่ไปกับ API ของนโยบายการทำธุรกรรมที่เฉพาะเจาะจง หากแอปพลิเคชันจำเป็นต้องเปลี่ยนกลยุทธ์หมายความว่ารหัสจะต้องมีการแก้ไขอย่างมาก แต่ถ้าคุณใช้ธุรกรรมสปริงจะไม่มีปัญหา
Sring ไม่ได้ให้การสนับสนุนการทำธุรกรรมใด ๆ แต่เป็นหน้าที่เฉพาะในการห่อธุรกรรมพื้นฐานและในระดับฤดูใบไม้ผลิจะให้ API การเขียนโปรแกรมแบบครบวงจรแก่โลกภายนอก แกนหลักของการทำธุรกรรมสปริงคืออินเทอร์เฟซ PlatformTransactionManager
PlatformTransactionManager แสดงถึงอินเทอร์เฟซการทำธุรกรรมที่เป็นอิสระจากประเภทเฉพาะและสามารถแสดงการทำธุรกรรมใด ๆ รวมถึงธุรกรรม JDBC ธุรกรรมไฮเบอร์เนตและแม้แต่ธุรกรรม JTA
กลไกการทำธุรกรรม Springa เป็นแบบจำลองนโยบายทั่วไป PlatformTransactionManager แสดงถึงอินเทอร์เฟซการจัดการธุรกรรม แต่ไม่ทราบวิธีการจัดการธุรกรรม ต้องใช้การจัดการธุรกรรมเท่านั้นเพื่อให้สามวิธี: เริ่มการทำธุรกรรม getTransaction(), commit() ธุรกรรมและ rollback() อย่างไรก็ตามการใช้งานที่เฉพาะเจาะจงจะถูกทิ้งให้อยู่ในระดับการใช้งานเพื่อให้เสร็จสมบูรณ์ โปรแกรมเมอร์จำเป็นต้องกำหนดค่าประเภทธุรกรรมในไฟล์การกำหนดค่าตามประเภทธุรกรรมเฉพาะที่ใช้ สปริงพื้นฐานจะใช้คลาสการใช้งานการทำธุรกรรมเฉพาะโดยอัตโนมัติเพื่อดำเนินการธุรกรรม สำหรับโปรแกรมเมอร์พวกเขาไม่จำเป็นต้องใส่ใจเกี่ยวกับกระบวนการพื้นฐานเลยพวกเขาจำเป็นต้องตั้งโปรแกรมสำหรับอินเทอร์เฟซ PlatformTransactionManager เท่านั้น อินเทอร์เฟซ PlatformTransactionManager ให้วิธีการต่อไปนี้: getTransaction(..), commit(); rollback(); นี่คือการดำเนินการธุรกรรมทั้งหมดที่ไม่เกี่ยวข้องกับแพลตฟอร์ม
การเขียนที่สมบูรณ์ของ getTransaction() คือ TransactionStatus getTransaction(TransactionDefinition definiton)
วิธีนี้ใช้เพื่อส่งคืนวัตถุธุรกรรมและพารามิเตอร์ transactionDefinition สามารถระบุแอตทริบิวต์ต่างๆสำหรับวัตถุธุรกรรม โดยปกติแล้วมันสามารถระบุคุณสมบัติการแยกของธุรกรรมคุณลักษณะการแพร่กระจายการหมดเวลาและอ่านเฉพาะแอตทริบิวต์เหล่านี้
การจัดการธุรกรรมเฉพาะของสปริงต้องการให้ PlatformTransactionManager ได้รับการกำหนดค่าในไฟล์การกำหนดค่า ต่อไปนี้คือการกำหนดค่าสปริงที่สอดคล้องกับประเภทของธุรกรรมที่แตกต่างกัน
การกำหนดค่าของตัวจัดการธุรกรรมท้องถิ่นของแหล่งข้อมูล JDBC มีดังนี้:
<!-กำหนดแหล่งข้อมูลแหล่งข้อมูลใช้แหล่งข้อมูล C3P0 เพื่อนำไปใช้และฉีดข้อมูลที่จำเป็นของแหล่งข้อมูล-> <bean id = "dataSource" destroy-method = "Close" P: driverclass = "com.mysql.jdbc.driver" P: MaxPoolSize = "40" P: MinPoolSize = "2" P: InitialPoolSize = "2" P: MaxidLetime = "30" /> <!-กำหนดค่าตัวจัดการข้อมูลท้องถิ่นสำหรับแหล่งข้อมูล JDBC ใช้ DataSourceTransactionManager
การกำหนดค่าของ JTA Global Transaction Manager สำหรับการจัดการคอนเทนเนอร์มีดังนี้:
<bean id = "DataSource" P: JnDiname = "JDBC /JPETSTORE" /> <!-การใช้คลาส JTATRANSActionManager คลาสนี้ใช้อินเทอร์เฟซ PlatformTransactionManager-> <!
สำหรับการทำธุรกรรม Global Global คุณจะต้องระบุคลาสการใช้งานของผู้จัดการการทำธุรกรรม JTATRANSACTIONMANAGANAGER คอนเทนเนอร์สปริงจะได้รับแหล่งข้อมูลจากเซิร์ฟเวอร์ J2EE ด้วยตัวเองโดยไม่ต้องฉีดเข้าไปในตัวจัดการธุรกรรมอย่างชัดเจน
การกำหนดค่าการทำธุรกรรมในพื้นที่ของฤดูใบไม้ผลิที่ใช้เทคโนโลยีการคงอยู่ของไฮเบอร์เนตมีดังนี้
<!-กำหนดแหล่งข้อมูลแหล่งข้อมูลใช้แหล่งข้อมูล C3P0 เพื่อนำไปใช้และฉีดข้อมูลที่จำเป็นของแหล่งข้อมูล-> <bean id = "dataSource" destroy-method = "Close" P: driverclass = "com.mysql.jdbc.driver" P: MaxPoolSize = "40" P: MinPoolSize = "2" P: InitialPoolSize = "2" P: maxidletime = "30" /> <!-กำหนดเซสชันการสร้างไฮเบอร์เนต, เซสชันที่ต้องพึ่งพาแหล่งข้อมูล ใช้ในการแสดงรายการคลาสถาวรทั้งหมด-> <property name = "AnnotatedClasses"> <list> <!-ต่อไปนี้ใช้ในการแสดงรายการคลาส PO ทั้งหมด-> <value> com.entity.user </value> </list> </คุณสมบัติ> <! key = "hibernate.dialect"> org.hibernate.dialect.mysql5innodbdialect </prop> <!-ไม่ว่าจะสร้างตารางข้อมูลตามตารางการทำแผนที่ hibernate-> <prop key = "hibernate.hbm2dl.auto" Manager, การใช้คลาส HiberNateTransactionManager-> <!-คลาสนี้เป็นการใช้งานเฉพาะของอินเทอร์เฟซ PlatformTransactionManager สำหรับ HiberNate-> <!-การกำหนดค่า hibernatetransactionManager ต้องใช้ SessionFactory-> <bean id = "transactionManager" p: sessionfactory-ref =
หากการทำธุรกรรมในฤดูใบไม้ผลิใช้นโยบายไฮเบอร์เนตโดยทั่วไปจะต้องมีสามคะแนนในการกำหนดค่า: แหล่งข้อมูล, เซสชั่น FACTORY และผู้จัดการธุรกรรม
หากเลเยอร์พื้นฐานใช้เทคโนโลยีการคงอยู่ของไฮเบอร์เนตและการทำธุรกรรมใช้ธุรกรรม Global JTA การกำหนดค่ามีดังนี้:
<!-กำหนดค่าแหล่งข้อมูล JTA-> <bean id = "dataSource" p: jndiname = "jdbc /jpetstore" /> <!-กำหนด sessionfactory hibernate SessionFactory จำเป็นต้องพึ่งพาแหล่งข้อมูลและการฉีด DataSource-> <bean id = "SessionFactory" P: DataSource-ref = "DataSource"> <!-AnnotatedClasses ใช้ในการแสดงรายการทั้งหมด-> <property name = "annotatedClasses"> <list> <! </perty> <!-กำหนดคุณสมบัติเซสชันของ Hibernate-> <property name = "HibernateProperties"> <props> <!-ระบุภาษาการเชื่อมต่อของ Hibernate-> <prop key = "hibernate.dialect"> org.hibernate.dialect.mysql5innodbdialial Tables-> <prop key = "hibernate.hbm2ddl.auto"> อัปเดต </prop> </props> </property> </ebean> <!-ใช้คลาส JTatransactionManager ซึ่งเป็นคลาสการใช้งานของ PlatformTransactionManager
เมื่อเทียบกับธุรกรรมสปริงที่ใช้ไฮเบอร์เนตก่อนหน้านี้คือการแทนที่แหล่งข้อมูลด้วยแหล่งข้อมูล JNDI และแทนที่ตัวจัดการธุรกรรมด้วย JTatransactionManager
สำหรับการทำธุรกรรม Global Global เนื่องจากการสนับสนุนของแอปพลิเคชันเซิร์ฟเวอร์พื้นฐานเป็นสิ่งจำเป็นอาจมีความแตกต่างในรายละเอียดระหว่างการทำธุรกรรม JTA ทั่วโลกที่จัดทำโดยเซิร์ฟเวอร์แอปพลิเคชันที่แตกต่างกัน ดังนั้นเมื่อกำหนดค่าตัวจัดการธุรกรรมทั่วโลกจริง ๆ คุณอาจต้องใช้คลาสย่อยของ JTatransactionManager เช่น OC4JJTATRANSActionManager ที่จัดทำโดยแอปพลิเคชันแอปพลิเคชัน Javaee ของ Oracle
จากการกำหนดค่าฤดูใบไม้ผลิของประเภทธุรกรรมที่หลากหลายด้านบนจะเห็นได้ว่าเมื่อแอปพลิเคชันใช้การจัดการธุรกรรมสปริงแอปพลิเคชันไม่จำเป็นต้องควบคู่กับการทำธุรกรรม API เฉพาะ แอปพลิเคชันจะต้องตั้งโปรแกรมไว้ในส่วนต่อประสาน PlatorMtransactionManager เท่านั้น ApplicationContext จะเลือกคลาสการใช้นโยบายการทำธุรกรรมที่เหมาะสม (เช่นคลาสการใช้งานของ PlatorMtransactionManager) ตามไฟล์การกำหนดค่า
ดังนั้นในรายละเอียดวิธีการเขียนโปรแกรมควบคุมธุรกรรมในฤดูใบไม้ผลิมักจะมีสองวิธี
การจัดการธุรกรรมการเขียนโปรแกรม: มันคือการใช้วิธีการนามธรรมทั้งสามโดยตรงโดย PlatorMtransactionManager เพื่อควบคุมการไหลของธุรกรรมในรหัส นอกจากนี้คุณยังสามารถรับถั่วประเภท platormtransactionmanager ในภาชนะฤดูใบไม้ผลิ ถั่วนี้เป็นตัวอย่างของคลาสการใช้งานเฉพาะของ PlatorMtransactionManager คลาสการใช้งานเฉพาะถูกเลือกโดย ApplicationContext ตามรูปแบบนโยบาย โปรแกรมเมอร์ไม่จำเป็นต้องใส่ใจพวกเขาเพียงแค่ต้องตั้งโปรแกรมที่มุ่งเน้นอินเทอร์เฟซ
การจัดการธุรกรรมที่ประกาศ: วิธีนี้ไม่จำเป็นต้องใช้กระบวนการควบคุมธุรกรรมลงในรหัส แต่ใช้ AOP เพื่อให้การรวมการทำธุรกรรมเสร็จสมบูรณ์ผ่านไฟล์การกำหนดค่า นั่นคือไฟล์การกำหนดค่า XML สามารถกำหนดค่าตัวแทนธุรกรรมสำหรับส่วนประกอบทางธุรกิจและตัวแทนธุรกรรมให้การควบคุมธุรกรรมสำหรับส่วนประกอบทางธุรกิจ ตอนนี้วิธีนี้ดีที่สุดด้วยการบุกรุกซอร์สโค้ดต่ำสุด
เมื่อใช้ธุรกรรมที่ประกาศคุณจะต้องเขียนไฟล์กำหนดค่าและกำหนดค่าประเภทของส่วนประกอบที่ต้องมีการควบคุมธุรกรรม ส่วนประกอบทางธุรกิจจะถูกทอในการควบคุมธุรกรรมภายใต้กลไก AOP และโปรแกรมเมอร์ไม่จำเป็นต้องเขียนรหัสการจัดการธุรกรรมใด ๆ และสามารถมุ่งเน้นไปที่การพัฒนาส่วนประกอบทางธุรกิจ ดังนั้นแนะนำการจัดการธุรกรรมที่ประกาศโดยทั่วไป
วิธี XML Schema ของ Spring ให้กลยุทธ์การกำหนดค่าการทำธุรกรรมที่รัดกุม มันกำหนดค่าการประมวลผลการเพิ่มประสิทธิภาพการทำธุรกรรมผ่านเนมสเปซ <tx:advice> ซึ่งสามารถระบุคุณลักษณะต่าง ๆ ของธุรกรรม (เช่นคุณลักษณะการแยก, แอตทริบิวต์การแพร่กระจาย, การหมดเวลา, คุณลักษณะการอ่านอย่างเดียว ฯลฯ ) และการเพิ่มการทำธุรกรรม วิธีการในการทำธุรกรรม นี่คือตัวอย่างง่ายๆการกำหนดค่าถั่ว NewsDaoimpl สำหรับการดำเนินการข้อมูลโดยใช้แหล่งข้อมูล C3P0, ผู้จัดการธุรกรรม JDBC ของ Spring และการตั้งค่าคุณสมบัติสำหรับการทำธุรกรรมใน <TX: คำแนะนำ
การกำหนดค่าสปริงที่สมบูรณ์มีดังนี้:
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <ถั่ว xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns = "http://www.springframeworkel xmlns: p = "http://www.springframework.org/schema/p" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http:/ XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http:/www.springframwork http://www.springframework.org/schema/aop http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework กำหนดแหล่งข้อมูลแหล่งข้อมูลใช้แหล่งข้อมูล C3P0 เพื่อนำไปใช้และฉีดข้อมูลที่จำเป็นของแหล่งข้อมูล-> <bean id = "DataSource" Destroy-method = "Close" P: driverclass = "com.mysql.jdbc.driver" p: jdbcurl = "jdbc: mysql P: user = "root" p: password = "" p: maxPoolSize = "40" P: minPoolSize = "2" P: InitialPoolSize = "2" P: maxidLetime = "30" /> <! /> <!-กำหนดค่าถั่วลอจิกธุรกิจ-> <bean id = "newsdao" p: ds-ref = "dataSource" /> <!-กำหนดค่าการประมวลผลการเพิ่มประสิทธิภาพการทำธุรกรรมระบุตัวจัดการธุรกรรม-> <tx: คำแนะนำ id = "txadvice" ด้วย Get เป็นแบบอ่านอย่างเดียว-> <tx: method name = "get*" read-only = "true" /> <!-วิธีอื่นทั้งหมดอยู่ภายใต้การทำธุรกรรมโดยค่าเริ่มต้นระบุการหมดเวลา 5 วินาที-> <tx: method name = "*" การแยกตัว: การกำหนดค่าเริ่มต้น เพื่อให้ตรงกับการดำเนินการของวิธีการทั้งหมดในคลาส INSPLEND ทั้งหมดภายใต้แพ็คเกจ INDIM-> <aop: pointcut expression = "การดำเนินการ (*com.dao.impl.*Impl.*(.. ))" id = "MyPointCut" /> <! <!-กำหนดค่าจุดเริ่มต้นอื่นเพื่อให้ตรงกับการดำเนินการของวิธีทั้งหมดในชั้นเรียนที่เริ่มต้นด้วย ABC ภายใต้แพ็คเกจ INTIM-> </aop: config> </epeans>
ในรหัส NewsDaoimpl มันคือการแทรกข้อมูลที่ซ้ำกันลงในตาราง
แพ็คเกจ com.dao.impl; นำเข้า javax.sql.datasource; นำเข้า org.springframework.jdbc.core.jdbctemplate; นำเข้า com.dao.newsdao; Newsdaoimpl Public เป็นโมฆะแทรก (ชื่อสตริงเนื้อหาสตริง) {// การใช้งานของ c3p0 พูลข้อมูล Jdbctemplate jt = jdbctemplate ใหม่ (ds); jt.update ("แทรกลงใน news_inf" + "ค่า (100,?,?)" การควบคุมการทำธุรกรรมบันทึกแรกสามารถแทรก // หากมีการเพิ่มการควบคุมธุรกรรมบันทึกแรกจะไม่ถูกแทรก}}นี่คือวิธีการทดสอบ
โมฆะคงที่สาธารณะ test3 () {ApplicationContext CTX = ใหม่ classPathxMlApplicationContext ("beans4jdbc.xml"); // รับตัวแทนธุรกรรมถั่ว Newsdao dao = (newsdao) ctx.getbean ("Newsdao", Newsdao.class); dao.insert ("แนวคิดหลักของการเขียนโปรแกรม Java", "การพัฒนา Java EE ที่มีน้ำหนักเบา"); System.out.println ("เสร็จสิ้นการดำเนินการ"); -การดำเนินการวิธีทดสอบจะพบว่ามีการโยนข้อยกเว้น (เนื่องจากข้อมูลซ้ำ) และเนื่องจากการควบคุมธุรกรรมจะไม่มีการแทรกข้อมูลในฐานข้อมูล
อย่างที่คุณเห็นในตัวอย่างข้างต้นมักจะอยู่ในการกำหนดค่า XML Schema การกำหนดค่า AOP จะทำจริงสำหรับถั่วธรรมดาและมีการเพิ่มคำแนะนำ การปรับปรุงคำแนะนำได้รับการกำหนดค่าด้วยตัวจัดการธุรกรรมซึ่งขึ้นอยู่กับแหล่งข้อมูล
สำหรับ <AOP: ที่ปรึกษา> การผูกมัดของคำแนะนำและจุดเริ่มต้นนั้นทำโดย postprocessor ถั่วที่ด้านล่างของฤดูใบไม้ผลิ (เช่น Beannameautoproxycreator, DefaultAdvisorautoproxycreator) ซึ่งเป็นพร็อกซีแบบไดนามิก
นอกจากนี้ใน <TX: คำแนะนำ> การปรับปรุงการกำหนดค่าคุณยังสามารถระบุได้ว่าเมื่อพบข้อยกเว้นเฉพาะการบังคับย้อนกลับและการบังคับไม่ย้อนกลับนั่นคือการย้อนกลับสำหรับ = "xxxException"
นอกเหนือจากการใช้วิธีการ XML Schema แล้วคุณยังสามารถเพิ่มคำอธิบายประกอบ @Transaction ลงในวิธีการที่จะทำให้วิธีนี้มีคุณสมบัติการทำธุรกรรมโดยตรง ใน @Transaction คุณสมบัติต่าง ๆ สามารถกำหนดค่าสำหรับการทำธุรกรรม (เช่นคุณสมบัติการแยกคุณสมบัติการแพร่กระจายการหมดเวลาคุณสมบัติการอ่านอย่างเดียว ฯลฯ ) นอกจากนี้ยังมีความจำเป็นที่จะต้องเพิ่มการกำหนดค่า <TX: การกำหนดค่าคำอธิบายประกอบในการกำหนดค่า XML ซึ่งบ่งชี้ว่าสปริงจะกำหนดค่าตัวแทนธุรกรรมตามคำอธิบายประกอบเพื่อให้การกำหนดค่าคุณสมบัติของการทำธุรกรรมและการกำหนดค่า AOP Cutting สามารถทำได้ในขั้นตอนเดียวเท่านั้น
<TX: Transaction-Driven Transaction-Manager = "TransactionManager" />>>
Newsdaoimpl
@TransActional (การแพร่กระจาย = การแพร่กระจาย. ต้องการ, แยก = isolation.default, หมดเวลา = 5) @Overridepublic void แทรก (ชื่อสตริง, เนื้อหาสตริง) {ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้เกี่ยวกับรหัสตัวอย่างกลไกการทำธุรกรรมของฤดูใบไม้ผลิและฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!