小码农的代码(二)----------SpringJDBC事务控制

继续上一篇文章中所述项目的代码整理学习,前面提到直接使用springJDBC的进行数据层的操作,事务控制是必须要有的,那么这里整理一下之前使用的事务控制内容。
首先Spring的事务控制是很完善的,能够满足本人目前遇到的几乎所有项目,具体的内容就不展开论述了,因为太多了 。这里贴一张图,基本就可以理清Spring事务控制的最基本配置。本图来源于博客园

由于实际项目周期的问题以及个人习惯能注解就注解=。=,当然因为某种原因,这里并不是使用纯注解的方式进行事务配置,而是使用了tx拦截器的方式进行声明式事务配置(入乡随俗,充分利用Spring特色),其中运用到的aop面向切面编程后续文章中会专门对他的aspectj代理机制进行总结,这里就不对其展开代码编写试验了,当然这里的项目aspectjweaver的JAR包是肯定要添加的
首先由于是直接使用SpringJdbc因而使用DataSourceTransactionManager进行事务管理
<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>其次自然需要开启tx标签注解事务
[code="java<!-- 开启注解事务 只对当前配置文件有效 -->
	<tx:annotation-driven transaction-manager="transactionManager" />

	<!-- 事务管理配置 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="create*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />
			<tx:method name="cancel*" propagation="REQUIRED" />

			<tx:method name="get*" propagation="REQUIRED" read-only="true" />
			<tx:method name="query*" propagation="REQUIRED" read-only="true" />
			<tx:method name="find*" propagation="REQUIRED" read-only="true" />
			<tx:method name="load*" propagation="REQUIRED" read-only="true" />
			<tx:method name="count*" propagation="REQUIRED" read-only="true" />
			<tx:method name="list*" propagation="REQUIRED" read-only="true" />
			<tx:method name="*" read-only="true" />
		</tx:attributes>
	</tx:advice>
最后开启Aop的监听与监听切面
<aop:aspectj-autoproxy expose-proxy="true" /><aop:config expose-proxy="true">
		<!-- 只对业务逻辑层实施事务 -->
		<aop:pointcut id="txPointcut"
			expression="execution(* com.zh..service.impl.*ServiceImpl.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
	</aop:config>
这样配置就结束了。对于不想使用切面直接使用纯注解方式后续的文章总结中可以尝试使用。
接下去就可以展开编码测试了,在上文的基础上新建了Service类,并加入@service注解,使得调用的时候可以自动注入
@Service("userService")
public class UserServiceImpl implements UserService{

	@Autowired
	private BaseDao baseDao;
	
		public void saveUser(String sql) {
		try {
			baseDao.addBySql("insert into user (name,age)values('张三',13)", null);
			baseDao.addBySql("insert into user (id,name,age)values(2,'张三',13)", null);
		} catch (Exception e) {
			System.out.println("代码错误新增事务回滚");
		}
	}

}
如果事务正常控制则因为第二条新增语句错误(因id为2的记录已存在,可自行修改)而catch到异常并且数据库中没有新增的记录(ps.数据库很简单,就死一张user表,有id,name,age三个字段,id为主键自增)。经测试,测试结果与预测一致。
ps:注意点:在dao层新增时,如果是以下情况则数据库直接新增前一条记录
public void addBySql(String sql,final Object[] params) {
				jdbcTemplate.execute(sql);
			
		}
因而保存语句应该使用PreparedStatement,
jdbcTemplate.update(sql,
				new PreparedStatementSetter() {
					public void setValues(PreparedStatement ps)
							throws SQLException {
						ps.setInt(1, Integer.parseInt(params[0].toString()));
					}
				});	
进入jdbcTemplate.execute()方法可以发现它是直接调用Statement.execute直接执行因为事实上数据库事务已经提交而调用update方法时是使用PreparedStatement进行预编译的。
测试代码见附件,以上内容如有错误 烦请斧正,希望能够在大家的指导下更进一步,谢谢。
下一篇博文将会对SpringJDBC的多数据源在本项目中的实际运用进行总结。

猜你喜欢

转载自675990021.iteye.com/blog/2265732