To learn more about starting a transaction with spring, let's take a look at this simple example:
1. entity class user. Java
Package Org. lab24.entity; </P> <p> Import Java. io. serializable; </P> <p> Import javax. persistence. entity; <br/> Import javax. persistence. generatedvalue; <br/> Import javax. persistence. generationtype; <br/> Import javax. persistence. ID; <br/> Import javax. persistence. table; </P> <p> @ entity <br/> @ table (name = "user ") <br/> public class user implements serializable {</P> <p> public user () {<br/>}</P> <p> @ ID <br/> @ generatedvalue (Strategy = generationtype. auto) <br/> private integer ID; <br/> private string name; </P> <p> Public integer GETID () {<br/> return ID; <br/>}< br/> Public void setid (integer ID) {<br/> This. id = ID; <br/>}< br/> Public String getname () {<br/> return name; <br/>}< br/> Public void setname (string name) {<br/> This. name = Name; <br/>}< br/>
2. Abstract DAO class. Here it is set as an abstract class mainly to prevent it from directly instantiating objects (this design seems a bit redundant here. This should be a design pattern ):
Package Org. lab24.dao; </P> <p> Import Java. util. list; </P> <p> Import Org. springframework. orm. hibernate3.support. hibernatedaosupport; </P> <p> public abstract class basicdao extends hibernatedaosupport {</P> <p> // return the value here. You can directly return gethibernatetemplate (). save (entity) value. This will return the key value of the newly inserted record. You can also return an object that persists to the database as follows <br/> Public object save (Object entity) throws exception {<br/> gethibernatetemplate (). save (entity); <br/> return entity; <br/>}</P> <p> public list getallobjects (Class Object) throws exception {<br/> return gethibernatetemplate (). find ("from" + object. getname (); <br/>}</P> <p> // Delete returns a null value because all records are deleted, no key value or returned object <br/> Public void Delete (Object entity) throws exception {<br/> gethibernatetemplate (). delete (entity); <br/>}< br/>
3 DAO implementation class:
Package Org. lab24.dao. impl; </P> <p> Import Java. util. list; </P> <p> Import Org. lab24.dao. basicdao; <br/> Import Org. springframework. stereotype. repository; <br/> Import Org. springframework. stereotype. service; <br/> Import Org. springframework. transaction. annotation. propagation; <br/> Import Org. springframework. transaction. annotation. transactional; </P> <p>/* <br/> * @ service is used to mark the components at the business layer. <br/> * @ controller is used to mark the control layer. Components (such as actions in struts), <br/> * @ repository is used to mark the data access component, that is, the DaO component. <br/> * and @ component refers to the component, you can use this annotation to label components that are not categorized. <Br/> */<br/> @ repository ("basicdaoservice") <br/>/* <br/> * readonly indicates whether the transaction is read-only, you cannot insert or update data. <br/> * propagation = propagation. required indicates that the transaction needs to be enabled to execute this class of instance method <br/> * rollbackfor = throwable. class indicates that the throwable class and its subclass (that is, an exception occurs) are used to roll back the current affairs. <br/> */<br/> @ transactional (readonly = false, propagation = propagation. required, rollbackfor = throwable. class) <br/> public class basicdaoimpl extends basicdao {</P> <p> @ override <br/> Public object save (Object entity) throws exception {<br/> return Super. save (entity); <br/>}</P> <p> @ override <br/> Public void Delete (Object entity) throws exception {<br/> super. delete (entity); <br/>}</P> <p> @ override <br/> public list getallobjects (Class Object) throws exception {<br/> List objectlist = super. getallobjects (object); <br/> return objectlist; <br/>}</P> <p >}< br/>
4. business layer interface class:
Package Org. lab24.service; </P> <p> Import Java. util. list; </P> <p> Import Org. lab24.entity. user; </P> <p> Public interface userservice {</P> <p> Public void save (User user) throws exception; </P> <p> public list getallusers () throws exception; </P> <p> Public void deleteuser (User user) throws exception; </P> <p >}< br/>
5 Business Layer implementation class:
Package Org. lab24.serviceimpl; </P> <p> Import Java. util. list; </P> <p> Import javax. annotation. resource; </P> <p> Import Org. lab24.dao. impl. basicdaoimpl; <br/> Import Org. lab24.entity. user; <br/> Import Org. lab24.service. userservice; <br/> Import Org. springframework. stereotype. service; </P> <p> @ Service ("userservice") // give the bean name managed by spring by yourself. If not, directly change the first letter of the class name to lowercase to form the bean name <br/> public class userserviceimpl implements userservice {</P> <p> @ resource <br/> basicdaoimpl basicdaoservice; // basicdaoservice corresponds to basicdaoimpl to become the bean name of the data access component </P> <p> public list getallusers () throws exception {<br/> List userlist = basicdaoservice. getallobjects (user. class); <br/> return userlist; <br/>}</P> <p> Public void save (User user) throws exception {<br/> basicdaoservice. save (User); <br/>}</P> <p> Public void deleteuser (User user) throws exception {<br/> basicdaoservice. delete (User); <br/>}</P> <p >}< br/>
6 test classes:
Package Org. lab24.junit. test; </P> <p> Import Java. util. iterator; <br/> Import Java. util. list; </P> <p> Import javax. annotation. resource; </P> <p> Import Org. JUnit. beforeclass; <br/> Import Org. JUnit. test; <br/> Import Org. JUnit. runner. runwith; <br/> Import Org. lab24.entity. user; <br/> Import Org. lab24.service. userservice; <br/> Import Org. springframework. test. context. contextconfiguration; <br/> Import Org. springframework. test. context. junit4.abstracttransactionaljunit4springcontexttests; <br/> Import Org. springframework. test. context. junit4.springjunit4classrunner; </P> <p> @ contextconfiguration (locations = "classpath: applicationcontext. XML ") <br/> @ runwith (springjunit4classrunner. class) </P> <p> public class userserviceimpltest {</P> <p> @ resource <br/> private userservice; // The userserviceimpl corresponding to userservice becomes the bean name of the service component </P> <p> @ beforeclass <br/> Public static void setupbeforeclass () throws exception {<br/>}</P> <p> @ test <br/> Public void testgetallusers () {<br/> List <user> Users = NULL; <br/> try {<br/> Users = userservice. getallusers (); <br/>}catch (exception e) {<br/> E. printstacktrace (); <br/>}< br/> iterator = users. iterator (); <br/> User temp; <br/> while (iterator. hasnext () {<br/> temp = (User) iterator. next (); <br/> system. out. println ("ID:" + temp. GETID () + "name:" + temp. getname (); <br/>}</P> <p> @ test <br/> Public void testsave () {<br/> User user = new user (); </P> <p> User. setname ("333333333"); <br/> try {<br/> userservice. save (User); <br/>}catch (exception e) {<br/> E. printstacktrace (); <br/>}</P> <p >}< br/>
7. Spring configuration file:
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <beans xmlns = "http://www.springframework.org/schema/beans" <br/> xmlns: DWR = "http://www.directwebremoting.org/schema/spring-dwr" <br/> xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" <br/> xmlns: context = "http://www.springframework.org/schema/context" <br/> xmlns: Tx = "http://www.springframework.org/schema/tx" <br/> xmlns: ehcache = "http://www.springmodules.org/schema/ehcache" <br/> xsi: schemalocat Ion = "http://www.springframework.org/schema/beans </P> <p> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd </P> <p> http://www.springframework.org/schema/context </P> <p> http://www.springframework.org/schema/context/spring-context-2.5.xsd </P> <p> http://www.springframework.org/schema/tx </P> <p> http://www.springframework.org/schema/tx/spring-tx-2.5.xsd </P> <p> http://www.springmodules.org/schema /Ehcache </P> <p> http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd </P> <p> http://www.directwebremoting.org/schema/spring-dwr </P> <p> http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd "<br/> default-autowire =" byname "default- lazy-init = "true"> </P> <p> <context: component-scan base-package = "org. lab24.dao. impl "/> <br/> <context: component-scan base-package =" org. lab24.serviceimpl "/> </P> <p> <bean id = "lobhandler" class = "org. springframework. JDBC. support. lob. defaultlobhandler "<br/> lazy-init =" true "/> </P> <p> <! -- Cache Management --> <br/> <bean id = "cachemanager" <br/> class = "org. springframework. cache. ehcache. ehcachemanagerfactorybean "> <br/> <property name =" configlocation "> <br/> <value> classpath: ehcache. XML </value> <br/> </property> </P> <p> </bean> </P> <p> <bean id = "sessionfactory" <br /> class = "org. springframework. orm. hibernate3.localsessionfactorybean "> <br/> <property name =" lobhandler "ref =" lobhandler "/> <br/> <property n Ame = "configurationclass" value = "org. hibernate. cfg. annotationconfiguration "/> <br/> <property name =" configlocation "> <br/> <value> classpath: hibernate. cfg. XML </value> <br/> </property> <br/> </bean> <br/> <bean id = "transactionmanager" <br/> class = "org. springframework. orm. hibernate3.hibernatetransactionmanager "> <br/> <property name =" sessionfactory "ref =" sessionfactory "/> <br/> </bean> </P> <p> <TX: Annotation -Driven transaction-Manager = "transactionmanager" <br/> proxy-target-class = "true"/> </P> <p> <! -- Perform automatic proxy configuration here --> <br/> <bean id = "beannameautoproxycreator" <br/> class = "org. springframework. AOP. framework. autoproxy. beannameautoproxycreator "> <br/> <property name =" proxytargetclass "value =" true "/> <br/> <property name =" beannames "> <br/> <list> <br/> <value> * impl </value> <br/> </List> <br/> </property> <br/> </bean> </P> <p> </beans> <br/>
8. hibernate configuration file:
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <! Doctype hibernate-configuration <br/> Public "-// hibernate/hibernate configuration DTD/EN" <br/> "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> </P> <p> <pibernate-Configuration> </P> <p> <session-factory> </P> <p> <property name = "hibernate. connection. driver_class "> COM. mySQL. JDBC. driver </property> <br/> <property name = "hibernate. dialect "> Org. hibernate. dialect. mysqldialect </property> <br/> <Property name = "hibernate. connection. username "> root </property> <br/> <property name =" hibernate. connection. password "> </property> <br/> <property name =" hibernate. connection. URL "> JDBC: mysql: // 127.0.0.1: 3306/wtb </property> </P> <p> <! -- Connection parameters --> <br/> <property name = "hibernate. connection. provider_class "> <br/> Org. hibernate. connection. c3p0connectionprovider <br/> </property> </P> <p> <! -- Connection pool --> <br/> <! -- The number of connections that c3p0 obtains at the same time when connections in the connection pool are exhausted. Default: 3 --> <br/> <property name = "hibernate. c3p0. acquireincrement"> 3 </property> </P> <p> <! -- Interval between two connections, in milliseconds. Default: 1000 --> <br/> <property name = "hibernate. c3p0. acquireretrydelay"> 1000 </property> <br/> <! -- When the connection is closed, all uncommitted operations are rolled back by default. Default: false --> <br/> <property name = "hibernate. c3p0. autocommitonclose"> false </property> <br/> <! -- The maximum number of connections retained in the connection pool. Default: 15 --> <br/> <property name = "hibernate. c3p0. maxpoolsize "> 15 </property> <br/> <property name =" hibernate. c3p0. max_size "> 20 </property> <br/> <property name =" hibernate. c3p0. min_size "> 5 </property> <br/> <property name =" hibernate. c3p0. timeout "> 5000 </property> </P> <p> <property name =" hibernate. c3p0. acquire_increment "> 5 </property> <br/> <property name =" hibernate. c3p0. idle_test_period "> 3000 </property> <br /> <Property name = "hibernate. c3p0. preferredtestquery "> <br/> select ID from test where id = 1 <br/> </property> <br/> <property name =" hibernate. c3p0. testconnectiononcheckin "> <br/> true <br/> </property> </P> <p> <! -- Delete the table in the database at startup, create it, and do not delete the data table at exit. If the following attributes are not available, manually write an SQL statement to create the table, to perform database operations --> <br/> <property name = "hbm2ddl. auto "> Update </property> </P> <p> <! -- <Br/> set the maximum depth for the Outer Join fetch tree of one-to-one (one-to-one) join. if the value is 0, the default outer connection is disabled. <br/> --> <br/> <property name = "hibernate. max_fetch_depth "> 3 </property> <br/> <property name =" hibernate. order_updates "> true </property> <br/> <property name =" hibernate. JDBC. fetch_size "> 100 </property> <br/> <property name =" hibernate. JDBC. batch_size "> 0 </property> <br/> <property name =" hibernate. show_ SQL "> false </property> <br/> <proper Ty name = "hibernate. format_ SQL "> true </property> </P> <p> <property name =" hibernate. EJB. naming_strategy "> <br/> defaultcomponentsafenamingstrategy <br/> </property> <br/> <property name =" hibernate. query. substitutions "> <br/> true = 1, false = 0 <br/> </property> <br/> <property name =" hibernate. query. factory_class "> <br/> Org. hibernate. hql. ast. astquerytranslatorfactory <br/> </property> <br/> <! -- <Br/> 2.0 <property <br/> name = "hibernate. query. factory_class "> Org. hibernate. hql. classic. classicquerytranslatorfactory </property> <br/> --> <br/> <property name = "hibernate. cglib. use_reflection_optimizer "> <br/> false <br/> </property> <br/> <property name =" hiberante. defaultautocommit "> false </property> </P> <p> <property name =" hibernate. cache. provider_class "> <br/> Org. hibernate. cache. ehcacheprovider <br/> </Property> <br/> <property name = "cache. use_second_level_cache"> true </property> </P> <p> <! -- Transaction configuration --> <br/> <property name = "hibernate. transaction. factory_class "> <br/> Org. hibernate. transaction. jdbctransactionfactory <br/> </property> </P> <p> <mapping class = "org. lab24.entity. user "/> </P> <p> </session-factory> </P> <p> </pibernate-configuration> <br/>
We can see from the DAO implementation class that it has the @ transactional tag, which requires that the transaction (Propagation
= Propagation. Required), because database operations must be performed in the form of transactions to ensure data consistency, you must enable the transaction if necessary.
Yes, we can also enable transactions at the business layer. For example, if you enable transactions in the DAO implementation class, spring calls the basicdaoimpl class instance
When the method is used, the transaction is started. After the method is completed, the transaction is committed, and a new record (such as the insert or update operation) is generated in the database.
The configuration in the userserviceimpl class also requires that the transaction be enabled. The transaction is committed only after the userserviceimpl method is completed, and the database information is obtained.
It is submitted after the basicdaoimpl class method is called, but it also depends on the transaction configuration method, that is, propagation settings, you can refer
The transaction settings mentioned in the previous blog.
Supplement basic transaction knowledge:
Database Transaction Concept
What is a database transaction?
A transaction is a program execution unit consisting of a series of operation sequences. These operations are either done or not done, which is an inseparable task.
Unit.
Four basic properties of database transactions (acid)
1. atomicity)
The atomicity of a transaction indicates that all operations contained in a transaction are either performed in full or not (all or none ).
2. Consistency)
Before a transaction starts, the database is in the consistent state. After the transaction ends, the database must also be in the consistent state.
For bank transfers, consistency requires that the execution of transactions should not change the sum of the two accounts A and B. Without such consistency requirements
Money may be born out of nothing, or it may be missing. Transactions should switch the database from one consistent state to another consistent state.
3. Isolation)
Transaction isolation requires the system to ensure that the transaction is not affected by other concurrent transactions, that is, to achieve this effect: For any pair of transactions T1 and
T2: In transaction T1, T2. execution is started only after T1. In this way, every transaction does not feel
Other transactions in the system are executed concurrently.
4. Durability)
Once a transaction is successfully completed, its changes to the database must be permanent and will not be lost even if the system encounters a fault. Data importance
Determines the importance of transaction persistence.