spring 版本 4.1.7
代码如下:
表:
CREATE TABLE users
(id
int(11) unsigned NOT NULL AUTO_INCREMENT,nick_name
varchar(100) DEFAULT NULL,password
varchar(100) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
INSERT INTO users
VALUES ('1', 'Jennifer', 'Alice');
INSERT INTO users
VALUES ('2', '爱', '克斯莱');
java 文件:
1)
package com.maxwell.spring.jdbc.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.maxwell.spring.jdbc.vo.User;
@Service
public class UserAopService
{
@Autowired
private UserDao dao;
public UserAopService()
{}
/**
* 此处的@Transactional注解把这个方法中的所有数据库操作当作事务进行处理
*/
public void testTransactionManager()
{
String nn = dao.addUser(new User().setNickName("Jensen").setPassword("jensen"));
int i = dao.getIdByNickName(nn);
System.out.println(i);
dao.setNickNameById(i, "Nimei");
}
}
2)
package com.maxwell.spring.jdbc.tx;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import com.maxwell.spring.jdbc.vo.User;
/**
- 用于测试事务
-
@author Techwork
*
*/
@Repository
public class UserDao {@Autowired
@Qualifier("npJdbcTpl")
private NamedParameterJdbcTemplate jdbcTpl;public String addUser(User user) {
String sql = "INSERT INTO users (nick_name, password) VALUES (:nickName, :password)";SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user); jdbcTpl.update(sql, paramSource); return user.getNickName();
}
public int getIdByNickName(String nickName) {
String sql = "select id, nick_name, password from users where nick_name = :xxx"; Map<String, Object> paramMap = new HashMap<>(); paramMap.put("xxx", nickName); RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class); List<User> users = jdbcTpl.query(sql, paramMap, rowMapper); if(users == null || users.size() < 1) { throw new RuntimeException("无此用户:" + nickName); } return users.get(0).getId();
}
public void setNickNameById(int id, String nickName) {
if(nickName.length() < 10) throw new RuntimeException("性别错误"); String sql = "update users set nick_name = :n where id = :i"; Map<String, Object> paramMap = new HashMap<>(); paramMap.put("n", nickName); paramMap.put("i", id); jdbcTpl.update(sql, paramMap);
}
}
3)
package com.maxwell.spring.jdbc.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import com.maxwell.spring.jdbc.vo.User;
@Service
public class UserService
{
@Autowired
private UserDao dao;
public UserService()
{}
/**
* 此处的@Transactional注解把这个方法中的所有数据库操作当作事务进行处理
*/
@Transactional
public void testTransactionManager()
{
String nn = dao.addUser(new User().setNickName("Jensen").setPassword("jensen"));
int i = dao.getIdByNickName(nn);
System.out.println(i);
dao.setNickNameById(i, "Nimei");
}
/**
* propagation: 指定事务的传播行为
* isolation: 指定事务的隔离级别
* noRollbackFor: 指定对哪些异常不回滚。通常取默认值。
* rollbackFor: 指定对哪些异常回滚。通常取默认值。
* readOnly: 只读事务。如果事务只读取数据,而不写数据的话,设置为true,有助于数据库引擎优化事务。
* timeout: 指定强制回滚事务(就算可能成功)之前,事务可以存在的时间,以防止事务占用数据库连接时间过长。
*/
@Transactional(isolation = Isolation.READ_COMMITTED, noRollbackFor = { Exception.class },
rollbackFor = { RuntimeException.class }, readOnly = true, timeout = 3)
public void testTransactionManager2()
{
String nn = dao.addUser(new User().setNickName("Jensen").setPassword("jensen"));
int i = dao.getIdByNickName(nn);
dao.setNickNameById(i, "哈哈");
}
}
4)
package com.maxwell.spring.jdbc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.maxwell.spring.jdbc.tx.UserAopService;
/**
- 测试AOP事务
- @author Angrynut
-
*/
public class AOPTransactionTest
{
private ApplicationContext ctx = null;
private UserAopService service = null;{
ctx = new ClassPathXmlApplicationContext("aoptx.xml");
service = ctx.getBean("userAopService", UserAopService.class);
}/**
- 1.测试AOP事务。 */ @Test public void testTransactionManager() { service.testTransactionManager(); }
}
spring 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<context:component-scan base-package="com.maxwell.spring.jdbc"/>
<!-- 数据源配置文件 -->
<util:properties id="db" location="classpath:db.properties"/>
<!-- 配置C3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="#{db['jdbc.user']}"/>
<property name="password" value="#{db['jdbc.password']}"/>
<property name="driverClass" value="#{db['jdbc.driverClass']}"/>
<property name="jdbcUrl" value="#{db['jdbc.jdbcUrl']}"/>
<property name="initialPoolSize" value="#{db['jdbc.initPoolSize']}"/>
<property name="maxPoolSize" value="#{db['jdbc.maxPoolSize']}"/>
</bean>
<bean id="npJdbcTpl" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.maxwell.spring.jdbc.tx.UserService.*(..))" id="pc"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
</aop:config>