ภาพรวม
การจัดการธุรกรรมเป็นสิ่งสำคัญสำหรับแอปพลิเคชันระดับองค์กรและสามารถมั่นใจได้ว่าข้อมูลความสอดคล้องแม้ว่าสถานการณ์ที่ผิดปกติจะเกิดขึ้น
Framework Spring เป็นนามธรรมที่สอดคล้องกันสำหรับการจัดการธุรกรรมโดยมีลักษณะดังนี้:
จัดเตรียมโมเดลการเขียนโปรแกรมที่สอดคล้องกันสำหรับ API การทำธุรกรรมที่แตกต่างกันเช่น JTA (Java Transaction API), JDBC, Hibernate, JPA (Java Persistence API และ JDO (วัตถุข้อมูล Java)
สนับสนุนการจัดการธุรกรรมที่ประกาศโดยเฉพาะอย่างยิ่งการจัดการธุรกรรมที่ประกาศขึ้นอยู่กับคำอธิบายประกอบซึ่งง่ายและใช้งานง่าย
ให้ API การจัดการธุรกรรมการเขียนโปรแกรมง่ายกว่า API การทำธุรกรรมอื่น ๆ เช่น JTA
การรวมที่สมบูรณ์แบบกับการเข้าถึงข้อมูลสปริงการเข้าถึง
วิธีการจัดการธุรกรรม
ฤดูใบไม้ผลิรองรับสองวิธี: การจัดการธุรกรรมเชิงโปรแกรมและการจัดการธุรกรรมที่ประกาศ
การจัดการธุรกรรมแบบโปรแกรมใช้ TransactionTemplate หรือใช้โดยตรง PlatformTransactionManager สำหรับการจัดการธุรกรรมแบบเป็นโปรแกรมสปริงแนะนำให้ใช้ TransactionTemplate
การจัดการธุรกรรมที่ประกาศเกิดขึ้นบน AOP สาระสำคัญของมันคือการสกัดกั้นวิธีการก่อนและหลังจากนั้นสร้างหรือเพิ่มธุรกรรมก่อนที่วิธีการเป้าหมายจะเริ่มขึ้น หลังจากดำเนินการวิธีการเป้าหมายการทำธุรกรรมจะถูกส่งหรือย้อนกลับตามสถานการณ์การดำเนินการ ข้อได้เปรียบที่ใหญ่ที่สุดของการทำธุรกรรมที่ประกาศคือพวกเขาไม่จำเป็นต้องจัดการธุรกรรมทางโปรแกรมดังนั้นจึงไม่จำเป็นต้องใช้รหัสการจัดการธุรกรรมเจือปนในรหัสตรรกะทางธุรกิจ เพียงทำการประกาศกฎการทำธุรกรรมที่เกี่ยวข้องในไฟล์การกำหนดค่า (หรือผ่านคำอธิบายประกอบ @Transactional) และคุณสามารถใช้กฎการทำธุรกรรมกับตรรกะทางธุรกิจ
เห็นได้ชัดว่าการจัดการธุรกรรมที่ประกาศนั้นดีกว่าการจัดการธุรกรรมแบบโปรแกรมซึ่งเป็นวิธีการพัฒนาที่ไม่รุกรานที่สนับสนุนในฤดูใบไม้ผลิ การจัดการธุรกรรมที่ประกาศให้รหัสธุรกิจปลอดจากการปนเปื้อน วัตถุ POJO ปกติสามารถรับการสนับสนุนการทำธุรกรรมที่สมบูรณ์โดยการเพิ่มคำอธิบายประกอบ เมื่อเปรียบเทียบกับธุรกรรมการเขียนโปรแกรมข้อเสียเพียงอย่างเดียวของการทำธุรกรรมที่ประกาศคือความละเอียดที่ดีที่สุดของหลังสามารถทำหน้าที่ได้ในระดับวิธีการเท่านั้นและไม่สามารถทำได้ในฐานะการทำธุรกรรมแบบโปรแกรมสามารถทำหน้าที่ได้ในระดับบล็อกรหัส อย่างไรก็ตามถึงแม้จะมีข้อกำหนดดังกล่าว แต่ก็มีวิธีแก้ปัญหามากมายเช่นบล็อกรหัสที่ต้องมีการจัดการธุรกรรมสามารถดำเนินการได้อย่างอิสระ ฯลฯ
นอกจากนี้ยังมีสองวิธีที่ใช้กันทั่วไปสำหรับการจัดการธุรกรรมที่ประกาศ หนึ่งคือไฟล์การกำหนดค่า XML ตามเนมสเปซ TX และ AOP และอีกไฟล์ขึ้นอยู่กับคำอธิบายประกอบ @Transactional เห็นได้ชัดว่าวิธีการที่ใช้คำอธิบายประกอบนั้นง่ายกว่าและใช้งานง่ายขึ้นและสดชื่นมากขึ้น
Automatic Commit (AutoCommit) และจะส่งโดยอัตโนมัติเมื่อปิดการเชื่อมต่อ
การส่งอัตโนมัติ
โดยค่าเริ่มต้นฐานข้อมูลอยู่ในโหมดการส่งอัตโนมัติ แต่ละคำสั่งอยู่ในธุรกรรมแยกต่างหาก เมื่อการดำเนินการของคำสั่งนี้เสร็จสิ้นหากการดำเนินการสำเร็จการทำธุรกรรมจะถูกส่งโดยปริยาย
หากการดำเนินการล้มเหลวธุรกรรมจะถูกย้อนกลับโดยปริยาย
สำหรับการจัดการธุรกรรมปกติชุดการดำเนินการที่เกี่ยวข้องอยู่ในการทำธุรกรรมดังนั้นโหมดการกระทำอัตโนมัติของฐานข้อมูลจะต้องปิด อย่างไรก็ตามเราไม่ต้องกังวลเกี่ยวกับเรื่องนี้ฤดูใบไม้ผลิจะตั้งค่าคุณสมบัติการกระทำอัตโนมัติของการเชื่อมต่อพื้นฐานกับเท็จ
org/springframework/jdbc/dataSource/dataSourceTransactionManager.java
// เปลี่ยนไปใช้งานด้วยตนเองหากจำเป็น สิ่งนี้มีราคาแพงมากในไดรเวอร์ JDBC บางตัว // ดังนั้นเราไม่ต้องการทำมันโดยไม่จำเป็น (ตัวอย่างเช่นถ้าเราได้กำหนดค่าพูลเชื่อมต่ออย่างชัดเจนเพื่อตั้งค่าไว้แล้ว) ถ้า (con.getautocommit ()) {txobject.setMustRestoreAutocommit (จริง); if (logger.isdebugenabled ()) {logger.debug ("การสลับการเชื่อมต่อ JDBC [" + con + "] เพื่อใช้งานด้วยตนเอง"); } con.setAutocommit (เท็จ);}พูลการเชื่อมต่อข้อมูลบางส่วนให้การตั้งค่าเพื่อปิดการทำธุรกรรมอัตโนมัติซึ่งเป็นการดีที่สุดที่จะปิดเมื่อตั้งค่าพูลการเชื่อมต่อ อย่างไรก็ตาม C3P0 ไม่ได้ให้คุณสมบัตินี้และสามารถพึ่งพาสปริงเพื่อตั้งค่าได้เท่านั้น
เนื่องจากข้อกำหนด JDBC กำหนดว่าเมื่อมีการสร้างวัตถุการเชื่อมต่อควรอยู่ในโหมดการกระทำอัตโนมัติซึ่งเป็นค่าเริ่มต้นใน DBMS และการกระทำอัตโนมัติจะต้องปิดอย่างชัดเจนหากจำเป็น C3P0 ปฏิบัติตามข้อกำหนดนี้และอนุญาตให้รหัสไคลเอนต์ตั้งค่าโหมดการส่งที่จำเป็นอย่างชัดเจน
ไม่ว่าจะส่งโดยอัตโนมัติเมื่อปิดการเชื่อมต่อ
เมื่อการเชื่อมต่อถูกปิดสิ่งที่ควรจัดการหากมีธุรกรรมที่ไม่มีข้อผูกมัด? ข้อกำหนด JDBC ไม่ได้กล่าวถึงว่านโยบายเริ่มต้นของ C3P0 คือการย้อนกลับธุรกรรมที่ไม่มีข้อผูกมัดใด ๆ นี่เป็นกลยุทธ์ที่ถูกต้อง แต่ไม่มีข้อตกลงระหว่างผู้ให้บริการไดรเวอร์ JDBC ในเรื่องนี้
คุณสมบัติ AutocommitonClose ของ C3P0 เป็นเท็จโดยค่าเริ่มต้นดังนั้นจึงไม่จำเป็นต้องไม่ย้าย หรือคุณสามารถตั้งค่าคุณสมบัตินี้เป็นเท็จได้อย่างชัดเจนซึ่งจะชัดเจนยิ่งขึ้น
การกำหนดค่าการจัดการธุรกรรมการประกาศตามคำอธิบายประกอบ
Spring-servlet.xml
<!-การสนับสนุนการทำธุรกรรม-> <!-PlatformTransActionMnager-> <bean id = "txManager"> <property name = "DataSource" ref = "DataSource" /> </ebean> <!-เปิดใช้งานการสนับสนุนการทำธุรกรรม
เพิ่มเนมสเปซ TX ใน Spring-servlet.xml
... xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: aop = "http://www.springframework.org/schema/aop. http://www.springframework.org/schema/tx/spring-tx.xsd ...
MyBatis มีส่วนร่วมโดยอัตโนมัติในการจัดการธุรกรรมฤดูใบไม้ผลิโดยไม่ต้องกำหนดค่าเพิ่มเติม ตราบใดที่แหล่งข้อมูลที่อ้างอิงโดย org.mybatis.spring.sqlsessionfactorybean สอดคล้องกับแหล่งข้อมูลที่อ้างอิงโดย DataSourceTransactionManager มิฉะนั้นการจัดการธุรกรรมจะไม่ทำงาน
นอกจากนี้คุณต้องดาวน์โหลดแพ็คเกจการพึ่งพา AOPALLIANCE.JAR และวางไว้ในไดเรกทอรี WEB-INF/LIB มิฉะนั้นจะมีการรายงานข้อยกเว้นเมื่อเริ่มต้นฤดูใบไม้ผลิ
java.lang.noclassdeffounderror: org/aopalliance/intercept/methodinterceptor
คุณสมบัติการทำธุรกรรมฤดูใบไม้ผลิ
คลาสนโยบายการจัดการธุรกรรมทั้งหมดในฤดูใบไม้ผลิได้รับการสืบทอดมาจาก org.springframework.transaction.platformTransactionManager
อินเทอร์เฟซสาธารณะ PlatformTransactionManager {TransactionStatus getTransaction (TransactionDefinition นิยาม) โยนธุรกรรม Exception; โมฆะ commit (transactionstatus สถานะ) พ่น transactionException; โมฆะย้อนกลับ (สถานะการทำธุรกรรมสถานะ) พ่น transactionException;}อินเทอร์เฟซ TransactionDefinition กำหนดลักษณะดังต่อไปนี้:
ระดับการแยกธุรกรรม
ระดับการแยกหมายถึงระดับการแยกระหว่างธุรกรรมที่เกิดขึ้นพร้อมกันหลายแห่ง ค่าคงที่ห้าค่าที่แสดงถึงระดับการแยกถูกกำหนดไว้ในส่วนต่อประสานการทำธุรกรรม:
TransactionDefinition.isolation_default: นี่คือค่าเริ่มต้นซึ่งระบุระดับการแยกเริ่มต้นที่ใช้สำหรับฐานข้อมูลพื้นฐาน สำหรับฐานข้อมูลส่วนใหญ่ค่านี้มักจะเป็น transactionDefinition.isolation_read_committed
TransactionDefinition.isolation_read_uncommitted: ระดับการแยกนี้บ่งชี้ว่าธุรกรรมหนึ่งสามารถอ่านข้อมูลที่แก้ไขโดยธุรกรรมอื่น แต่ยังไม่ได้กระทำ ระดับนี้ไม่ได้ป้องกันการอ่านที่สกปรกการอ่านซ้ำ ๆ และการอ่าน phantom ดังนั้นระดับการแยกนี้ไม่ค่อยใช้ ตัวอย่างเช่น PostgreSQL ไม่ได้มีระดับนี้
TransactionDefinition.isolation_Read_Committed: ระดับการแยกนี้หมายความว่าธุรกรรมหนึ่งสามารถอ่านข้อมูลที่เกิดขึ้นจากการทำธุรกรรมอื่นเท่านั้น ระดับนี้ป้องกันการอ่านที่สกปรกซึ่งเป็นค่าที่แนะนำในกรณีส่วนใหญ่
TransactionDefinition.isolation_repeatable_read: ระดับการแยกนี้บ่งชี้ว่าการทำธุรกรรมสามารถดำเนินการค้นหาหลายครั้งตลอดกระบวนการและบันทึกที่ส่งคืนจะเหมือนกันในแต่ละครั้ง ระดับนี้ป้องกันการอ่านที่สกปรกและไม่สามารถทำซ้ำได้
TransactionDefinition.isolation_serializable: การทำธุรกรรมทั้งหมดดำเนินการทีละหนึ่งตามลำดับเพื่อไม่ให้เกิดการรบกวนระหว่างการทำธุรกรรมนั่นคือระดับนี้สามารถป้องกันการอ่านที่สกปรก แต่สิ่งนี้จะส่งผลกระทบต่อประสิทธิภาพของโปรแกรมอย่างจริงจัง ระดับนี้ไม่ได้ใช้
พฤติกรรมการสื่อสารการทำธุรกรรม
พฤติกรรมการแพร่กระจายการทำธุรกรรมที่เรียกว่าหมายถึงหากมีบริบทการทำธุรกรรมอยู่แล้วก่อนที่จะเริ่มการทำธุรกรรมในปัจจุบันมีหลายตัวเลือกที่สามารถระบุพฤติกรรมการดำเนินการของวิธีการทำธุรกรรม คำจำกัดความของ TransactionDefinition รวมถึงค่าคงที่ต่อไปนี้ที่แสดงถึงพฤติกรรมการแพร่กระจาย:
TransactionDefinition.propagation_Required: หากมีการทำธุรกรรมในปัจจุบันให้เข้าร่วมการทำธุรกรรม หากไม่มีธุรกรรมในปัจจุบันให้สร้างธุรกรรมใหม่ นี่คือค่าเริ่มต้น
TransactionDefinition.propagation_requires_New: สร้างธุรกรรมใหม่และหากมีการทำธุรกรรมในปัจจุบันธุรกรรมปัจจุบันจะถูกระงับ
TransactionDefinition.propagation_supports: เข้าร่วมการทำธุรกรรมหากมีการทำธุรกรรมในปัจจุบัน หากไม่มีการทำธุรกรรมในปัจจุบันก็ยังคงดำเนินต่อไปในลักษณะที่ไม่ใช่การทำธุรกรรม
TransactionDefinition.propagation_not_supported: ทำงานในลักษณะที่ไม่ใช่การทำธุรกรรมและหากมีการทำธุรกรรมในปัจจุบันธุรกรรมปัจจุบันจะถูกระงับ
TransactionDefinition.propagation_never: ทำงานในลักษณะที่ไม่ใช่การทำธุรกรรมจะมีข้อยกเว้นหากมีการทำธุรกรรมอยู่ในปัจจุบัน
TransactionDefinition.propagation_mandatory: เข้าร่วมธุรกรรมหากมีการทำธุรกรรมในปัจจุบัน หากไม่มีธุรกรรมในปัจจุบันข้อยกเว้นจะถูกโยนลงไป
TransactionDefinition.propagation_nested: หากมีการทำธุรกรรมในปัจจุบันธุรกรรมจะถูกสร้างขึ้นเพื่อเรียกใช้เป็นธุรกรรมซ้อนของธุรกรรมปัจจุบัน หากไม่มีธุรกรรมค่าจะเท่ากับ TransactionDefinition.propagation_Required
หมดเวลาการทำธุรกรรม
การหมดเวลาการทำธุรกรรมที่เรียกว่าหมายถึงเวลาสูงสุดที่อนุญาตโดยการทำธุรกรรม หากเกินขีด จำกัด เวลา แต่การทำธุรกรรมยังไม่เสร็จสมบูรณ์การทำธุรกรรมจะถูกย้อนกลับโดยอัตโนมัติ ใน TransactionDefinition การหมดเวลาจะแสดงด้วยค่าของ Int และหน่วยของมันคือวินาที
การตั้งค่าเริ่มต้นคือค่าหมดเวลาของระบบธุรกรรมพื้นฐาน หากระบบธุรกรรมฐานข้อมูลพื้นฐานไม่ได้ตั้งค่าการหมดเวลาแสดงว่าไม่มีและไม่มีขีด จำกัด การหมดเวลา
คุณลักษณะการอ่านแบบอ่านอย่างเดียว
การทำธุรกรรมแบบอ่านอย่างเดียวใช้ในสถานการณ์ที่รหัสไคลเอนต์เป็นแบบอ่านอย่างเดียว แต่ไม่ได้แก้ไขข้อมูล การทำธุรกรรมแบบอ่านอย่างเดียวใช้ในการเพิ่มประสิทธิภาพในสถานการณ์เฉพาะเช่นเมื่อใช้ไฮเบอร์เนต
ค่าเริ่มต้นคือการอ่านและเขียนธุรกรรม
กฎการย้อนกลับของการทำธุรกรรมฤดูใบไม้ผลิ
วิธีที่แนะนำในการสั่งให้ผู้จัดการธุรกรรมสปริงย้อนกลับการทำธุรกรรมคือการโยนข้อยกเว้นภายในบริบทของธุรกรรมปัจจุบัน ผู้จัดการธุรกรรมสปริงจับข้อยกเว้นที่ไม่ได้รับการจัดการแล้วตัดสินใจว่าจะย้อนกลับการทำธุรกรรมที่ทำให้เกิดข้อยกเว้นตามกฎหรือไม่
โดยค่าเริ่มต้นสปริงจะย้อนกลับการทำธุรกรรมหากข้อยกเว้นที่โยนเป็นข้อยกเว้นที่ไม่ได้ตรวจสอบรันไทม์นั่นคือข้อยกเว้นที่ถูกโยนทิ้งเป็นคลาสย่อยของ RuntimeException (ข้อผิดพลาดจะทำให้เกิดการย้อนกลับของธุรกรรม)
เป็นไปได้ที่จะกำหนดค่าการทำธุรกรรมอย่างชัดเจนเพื่อย้อนกลับเมื่อมีการโยนข้อยกเว้นเหล่านั้นรวมถึงข้อยกเว้นที่ตรวจสอบ นอกจากนี้ยังเป็นไปได้ที่จะกำหนดธุรกรรมเหล่านั้นอย่างชัดเจนที่ไม่ย้อนกลับเมื่อมีการโยนข้อยกเว้น
นอกจากนี้คุณยังสามารถใช้วิธีการ setRollBackOnly () โดยทางโปรแกรมเพื่อระบุว่าการทำธุรกรรมจะต้องย้อนกลับ สิ่งเดียวที่คุณสามารถทำได้หลังจากโทร SetRollBackonly () คือการย้อนกลับ
@Transactional คำอธิบายประกอบ
@Transactional คุณสมบัติ
| คุณสมบัติ | พิมพ์ | อธิบาย |
|---|---|---|
| ค่า | สาย | ตัวบ่งชี้คัดเลือกที่เป็นตัวเลือกโดยระบุตัวจัดการธุรกรรมที่จะใช้ |
| การแพร่กระจาย | enum: การแพร่กระจาย | การตั้งค่าพฤติกรรมการเผยแพร่ธุรกรรมทางเลือก |
| การแยกตัว | enum: การแยก | การตั้งค่าระดับการแยกธุรกรรมเสริม |
| อย่างอ่านอย่างเดียว | บูลีน | อ่านและเขียนหรือทำธุรกรรมแบบอ่านอย่างเดียวอ่านเริ่มต้นและเขียน |
| การหมดเวลา | int (ในไม่กี่วินาทีความละเอียด) | การตั้งค่าการหมดเวลาการทำธุรกรรม |
| ย้อนกลับ | อาร์เรย์วัตถุคลาสจะต้องสืบทอดมาจากการโยนได้ | อาร์เรย์ของคลาสข้อยกเว้นที่ทำให้เกิดการย้อนกลับการทำธุรกรรม |
| RollbackForClassName | อาร์เรย์ของชื่อคลาสจะต้องสืบทอดมาจากการโยนได้ | อาร์เรย์ของชื่อคลาสข้อยกเว้นที่ทำให้เกิดการย้อนกลับธุรกรรม |
| นอร์ลอลล์แบ็ค | อาร์เรย์วัตถุคลาสจะต้องสืบทอดมาจากการโยนได้ | อาร์เรย์คลาสข้อยกเว้นที่ไม่ก่อให้เกิดการย้อนกลับธุรกรรม |
| norollbackforclassName | อาร์เรย์ของชื่อคลาสจะต้องสืบทอดมาจากการโยนได้ | อาร์เรย์ของชื่อคลาสข้อยกเว้นที่จะไม่ทำให้เกิดการย้อนกลับธุรกรรม |
การใช้งาน
@Transactional สามารถดำเนินการบนอินเทอร์เฟซวิธีการเชื่อมต่อคลาสและวิธีการเรียน เมื่อทำหน้าที่ในชั้นเรียนวิธีการสาธารณะทั้งหมดของชั้นเรียนจะมีคุณสมบัติการทำธุรกรรมประเภทนั้น ในเวลาเดียวกันเรายังสามารถใช้คำอธิบายประกอบนี้ในระดับวิธีการเพื่อแทนที่คำจำกัดความระดับชั้นเรียน
แม้ว่าคำอธิบายประกอบ @Transactional สามารถนำไปใช้กับอินเทอร์เฟซวิธีการเชื่อมต่อคลาสและวิธีการเรียนสปริงแนะนำไม่ให้ใช้คำอธิบายประกอบนี้กับอินเทอร์เฟซหรือวิธีการอินเตอร์เฟสเนื่องจากสิ่งนี้จะมีผลเมื่อใช้พร็อกซีที่ใช้อินเทอร์เฟซ นอกจากนี้ควรใช้คำอธิบายประกอบ @Transactional กับวิธีการสาธารณะเท่านั้นซึ่งจะถูกกำหนดโดยธรรมชาติของฤดูใบไม้ผลิ AOP หากคุณใช้คำอธิบายประกอบ @Transactional บนวิธีการที่ได้รับการป้องกันส่วนตัวหรือเริ่มต้นการมองเห็นสิ่งนี้จะถูกละเว้นและจะไม่มีข้อยกเว้นใด ๆ
โดยค่าเริ่มต้นการโทรจากภายนอกจะถูกจับโดยพร็อกซี AOP นั่นคือการเรียกใช้วิธีอื่นภายในคลาสนี้ภายในชั้นเรียนจะไม่ทำให้เกิดพฤติกรรมการทำธุรกรรมแม้ว่าวิธีที่เรียกว่าจะถูกแก้ไขโดยใช้คำอธิบายประกอบ @Transactional
@TransActional (readOnly = true) คลาสสาธารณะ defaultFooService ใช้ fooservice {public foo getfoo (สตริง fooname) {// ทำอะไรบางอย่าง} // การตั้งค่าเหล่านี้มีความสำคัญสำหรับวิธีนี้ // แอตทริบิวต์คำอธิบายประกอบการเสนอชื่อ UpdateFoo (foo foo) {// ทำอะไร}}สรุป
ข้างต้นเป็นเนื้อหาทั้งหมดของการตีความของบทความนี้เกี่ยวกับการใช้คำอธิบายประกอบ @Transactional ในฤดูใบไม้ผลิและฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!