Few people use Spring instead of Spring Transaction Manager applications. Therefore, some people often ask: if Spring is used, you must use Spring Transaction Manager, otherwise, what about data persistence? What is the relationship between the Transaction Manager and DAO? Maybe it is because DAO and transaction management are accompanied by shadows. This seemingly simple problem actually exists, and comes out of the minds of beginners, lingering in the minds of veterans. Of course, the answer is no! We all know that transaction management is to ensure that data operations are transactional (I .e., atomicity, consistency, isolation, durability, or ACID, DAO can perform data operations smoothly.
JDBC database access
Next, let's look at a piece of code that uses Spring JDBC for data access:
01 <SPAN style = "FONT-SIZE: 14px; COLOR: #006600; FONT-FAMILY: Microsoft YaHei" minmax_bound = "true"> package com. baobaotao. withouttx. jdbc;
02
03 import org. springframework. beans. factory. annotation. Autowired;
04 import org. springframework. jdbc. core. JdbcTemplate;
05 import org. springframework. stereotype. Service;
06 import org. springframework. context. ApplicationContext;
07 import org. springframework. context. support. ClassPathXmlApplicationContext;
08 import org. apache. commons. dbcp. BasicDataSource;
09
10 @ Service ("userService ")
11 public class UserJdbcWithoutTransManagerService {
12 @ Autowired
13 private JdbcTemplate jdbcTemplate;
14
15 public void addScore (String userName, int toAdd ){
16 String SQL = "UPDATE t_user u SET u. score = u. score +? WHERE user_name =? ";
17 jdbcTemplate. update (SQL, toAdd, userName );
18}
19
20 public static void main (String [] args ){
21 ApplicationContext ctx = new
22 ClassPathXmlApplicationContext ("com/baobaotao/withouttx/jdbc/jdbcWithoutTx. xml ");
23 UserJdbcWithoutTransManagerService service =
24 (UserJdbcWithoutTransManagerService) ctx. getBean ("userService ");
25 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx. getBean ("jdbcTemplate ");
26 BasicDataSource basicDataSource = (BasicDataSource) jdbcTemplate. getDataSource ();
27
28 // ① check the autoCommit settings of the Data Source
29 System. out. println ("autoCommit:" + basicDataSource. getDefaultAutoCommit ());
30
31 // ② insert a record with an initial score of 10
32 jdbcTemplate.exe cute ("insert into t_user (user_name, password, score, last_logon_time)
33 VALUES ('Tom ', '123', 10, "+ System. currentTimeMillis () + ")");
34
35 // ③ call the service class method working in a non-transaction environment and add the score to 20 points
36 service. addScore ("tom", 20 );
37
38 // ④ view the user's score
39 int score = jdbcTemplate. queryForInt (
40 "SELECT score FROM t_user WHERE user_name = 'Tom '");
41 System. out. println ("score:" + score );
42 jdbcTemplate.exe cute ("delete from t_user WHERE user_name = 'Tom '");
43}
44}
45 </SPAN>
The configuration file of jdbcWithoutTx. xml is as follows:
01 <SPAN style = "FONT-SIZE: 14px; COLOR: #006600; FONT-FAMILY: Microsoft YaHei" minmax_bound = "true"> <? Xml version = "1.0" encoding = "UTF-8"?>
02 <beans xmlns = "http://www.springframework.org/schema/beans"
03 xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
04 xmlns: context = "http://www.springframework.org/schema/context"
05 xmlns: p = "http://www.springframework.org/schema/p"
06 xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
07 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
08 <context: component-scan base-package = "com. baobaotao. withouttx. jdbc"/>
09
10 <context: property-placeholder location = "classpath: jdbc. properties"/>
11 <bean id = "dataSource" class = "org. apache. commons. dbcp. BasicDataSource"
12 destroy-method = "close"
13 p: driverClassName = "$ {jdbc. driverClassName }"
14 p: url = "$ {jdbc. url }"
15 p: username = "$ {jdbc. username }"
16 p: password = "$ {jdbc. password}"/>
17
18 <bean id = "jdbcTemplate" class = "org. springframework. jdbc. core. JdbcTemplate"
19 p: dataSource-ref = "dataSource"/>
20 </beans> </SPAN>
Run UserJdbcWithoutTransManagerService and output the following results on the console:
Reference
DefaultAutoCommit: true
Score: 30
In jdbcWithoutTx. xml, no transaction manager is configured, but the data is successfully persisted to the database. By default, the autoCommit Of The dataSource data source is set to true -- this means that all statements executed through JdbcTemplate are committed immediately and no transactions exist. If defaultAutoCommit of dataSource is set to false and UserJdbcWithoutTransManagerService is run again, an error is thrown because the operations for adding and changing data are not submitted to the database, therefore, the statement at the 10-1 4 in the code list cannot be found from the database and causes an exception.
For applications that emphasize read speed, the database itself may not support transactions, for example, MySQL databases using the MyISAM engine. At this time, you do not need to configure the Transaction Manager in the Spring application, because even if you configure it, it is useless.
Access the database through Hibernate
For Hibernate, the situation is a bit complicated. Because Hibernate's transaction management has its own meaning, it is closely related to Hibernate's level-1 cache: When we call methods such as Session save and update, hibernate does not directly send SQL statements to the database. It only sends SQL statements to the database when a transaction (commit) or flush level-1 cache is committed. Therefore, even if the underlying database does not support transactions, Hibernate's transaction management also has some benefits and will not negatively affect the efficiency of data operations. Therefore, if you use the Hibernate data access technology, there is no reason not to configure the HibernateTransactionManager Transaction Manager.
However, without using the Hibernate Transaction Manager, Hibernate can still work in Spring. Here is an example:
01 <SPAN style = "FONT-SIZE: 14px; COLOR: #006600; FONT-FAMILY: Microsoft YaHei" minmax_bound = "true"> package com. baobaotao. withouttx. hiber;
02
03 import org. springframework. beans. factory. annotation. Autowired;
04 import org. springframework. core. io. ClassPathResource;
05 import org. springframework. core. io. Resource;
06 import org. springframework. jdbc. core. JdbcTemplate;
07 import org. springframework. jdbc. core. simple. SimpleJdbcTemplate;
08 import org. springframework. stereotype. Service;
09 import org. springframework. context. ApplicationContext;
10 import org. springframework. context. support. ClassPathXmlApplicationContext;
11 import org. springframework. orm. hibernate3.HibernateTemplate;
12 import org. apache. commons. dbcp. BasicDataSource;
13 import org. springframework. test. jdbc. SimpleJdbcTestUtils;
14
15 import com. baobaotao. User;
16
17 @ Service ("hiberService ")
18 public class UserHibernateWithoutTransManagerService {
19
20 @ Autowired
21 private HibernateTemplate hibernateTemplate;
22
23 public void addScore (String userName, int toAdd ){
24 User user = hibernateTemplate. get (User. class, userName );
25 user. setScore (user. getScore () + toAdd );
26 hibernateTemplate. update (user );
27}
28
29 public static void main (String [] args ){
30 ApplicationContext ctx = new
31 ClassPathXmlApplicationContext ("com/baobaotao/withouttx/hiber/hiberWithoutTx. xml ");
32 UserHibernateWithoutTransManagerService service =
33 (UserHibernateWithoutTransManagerService) ctx. getBean ("hiberService ");
34
35 JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx. getBean ("jdbcTemplate ");
36 BasicDataSource basicDataSource = (BasicDataSource) jdbcTemplate. getDataSource ();
37
38 // ① check the autoCommit settings of the Data Source
39 System. out. println ("autoCommit:" + basicDataSource. getDefaultAutoCommit ());
40
41 // ② insert a record with an initial score of 10
42 jdbcTemplate.exe cute ("insert into t_user (user_name, password, score, last_logon_time)
43 VALUES ('Tom ', '123', 10, "+ System. currentTimeMillis () + ")");
44
45 // ③ call the service class method working in a non-transaction environment and add the score to 20 points
46 service. addScore ("tom", 20 );
47
48 // ④ view the user's score
49 int score = jdbcTemplate. queryForInt (
50 "SELECT score FROM t_user WHERE user_name = 'Tom '");
51 System. out. println ("score:" + score );
52 jdbcTemplate.exe cute ("delete from t_user WHERE user_name = 'Tom '");
53}
54} </SPAN>
In this case, the configuration file hiberWithoutTx. xml is used. The configuration content is as follows:
01 <SPAN style = "FONT-SIZE: 14px; COLOR: #006600; FONT-FAMILY: Microsoft YaHei" minmax_bound = "true"> <? Xml version = "1.0" encoding = "UTF-8"?>
02 <beans xmlns = "http://www.springframework.org/schema/beans"
03 xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
04 xmlns: context = "http://www.springframework.org/schema/context"
05 xmlns: p = "http://www.springframework.org/schema/p"
06 xsi: schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
07 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd ">
08 <context: component-scan base-package = "com. baobaotao. withouttx. hiber"/>
09...
10 <bean id = "sessionFactory"
11 class = "org. springframework. orm. hibernate3.annotation. AnnotationSessionFactoryBean"
12 p: dataSource-ref = "dataSource">
13 <property name = "annotatedClasses">
14 <list>
15 <value> com. baobaotao. User </value>
16 </list>
17 </property>
18 <property name = "hibernateProperties">
19 <props>
20 <prop key = "hibernate. dialect"> org. hibernate. dialect. MySQLDialect </prop>
21 <prop key = "hibernate. show_ SQL"> true </prop>
22 </props>
23 </property>
24 </bean>
25
26 <bean id = "hibernateTemplate"
27 class = "org. springframework. orm. hibernate3.HibernateTemplate"
28 p: sessionFactory-ref = "sessionFactory"/>
29
30 </beans> </SPAN>
Com. baobaotao. User is a domain object that uses the Hibernate annotation. The Code is as follows:
View sourceprint? 01 <SPAN style = "FONT-SIZE: 14px; COLOR: #006600; FONT-FAMILY: Microsoft YaHei" minmax_bound = "true"> package com. baobaotao;
02
03 import javax. persistence. Entity;
04 import javax. persistence. Table;
05 import javax. persistence. Column;
06 import javax. persistence. Id;
07 import java. lang. reflect. Field;
08 import java. io. Serializable;
09
10 @ Entity
11 @ Table (name = "T_USER ")
12 public class User implements Serializable {
13 @ Id
14 @ Column (name = "USER_NAME ")
15 private String userName;
16
17 private String password;
18
19 private int score;
20
21 @ Column (name = "LAST_LOGON_TIME ")
22 private long lastLogonTime = 0;
23
24...
25} </SPAN> www.2cto.com
Run UserHibernateWithoutTransManagerService. The program is correctly executed and the execution result is similar to UserJdbcWithoutTransManagerService. This shows that Hibernate can still access data normally without the Transaction Manager in Spring.