spring框架。声明事务全xml方式和半xml半注解方式

spring的声明式事务

        事务有什么特性: ACID

        原子性: 一件完成的事情,要不全部成功 要不全部失败

            转账: 加钱 减钱

        一致性: 事务的前后,数据总数不发生变化

            jack 1000   rose 1000   2000

            jack 500    rose 1500   2000

        持久性: 只要事务已完成(提交),数据就会到数据库中

        隔离性: 事务具备隔离性,如果没有隔离性,会发送读取数据的问题

        不具备隔离性的话,会发生什么问题: 

             会发送读取数据的问题

                脏读: 在一个事务中,读取到了另一个事务还没有提交的数据   必须杜绝的

                        ps:所有的数据库都自动避免的脏读

                重复读:在一个事务中,2次读取到的数据内容不一致(update)    可以允许

                虚读/幻读:在一个事务中,2次读取到的数据内容不一致(insert) 可以允许

        可以通过调整数据库的隔离级别,避免以上问题的发生:

            设置隔离级别

                    read uncommitted 效率最高 安全最低

                    read committed oracle

                    repeatable read mysql

                    serializable  安全最高 效率最低

转账案例

1 导包
            spring-tx.jar
        2 事务依赖aop
            AOP联盟
            spring-aop.jar
            aspectj.jar
            spring-aspects.jar

          引入tx aop约束文件

        3 编码
            1  确定目标类 (TranFerServiceImpl --tranfer)

            2  确定切面类 (用人家的 因为spring有一个类,里面都是事务的方法)
                DataSourceTransactionManager
                         提交
                         回滚
               增强方法:都是关于事务的
               细节: 得为配了这些事务增强方法的tanfer配置一些事务参数
                            是否只读
                            超时时间
                            传播行为

            3 配置织入 
                 专门针对事务的标签
                 指定那个事务用于那个切入点

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/atm?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
jdbc.username=root
jdbc.password=123


#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:oracle://localhost:3306/hibernate
#jdbc.username=root
#jdbc.password=1234


#jdbc.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:db2://localhost:3306/hibernate
#jdbc.username=root
#jdbc.password=1234

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!-- spring加载src下的properties文件 -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
        
   <!-- c3p0 -->
    <bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>
	
	<!-- jdbcTemplate -->
	<bean id="jdbctemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="c3p0"></property>
	</bean>
	
	<!-- tranFerDao -->
	<bean id="tranFerDao" class="com.it.daoimpl.TranFerDaoImpl">
		<property name="jdbctemplate" ref="jdbctemplate"></property>
	</bean>
	
	<!-- tranFerService 目标类 -->
	<bean id="tranFerService" class="com.it.serviceimpl.TranFerServiceImpl">
		<property name="tranFerDao" ref="tranFerDao"></property>
	</bean>
	
	<!-- 切面类 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="c3p0"> </property>
	</bean>
	
	<!-- 配置DataSourceTransactionManager里面事务方法的一些参数
		 不写 该方法使用的事务参数都是默认值
	 -->
	<tx:advice transaction-manager="transactionManager" id="txadvice">
			<tx:attributes>
			<!-- 指定方法名称:是业务核心方法  
			read-only:是否是只读事务。默认 false,不只读。  
			isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。 
			propagation:指定事务的传播行为。  timeout:指定超时时间。默认值为:-1。永不超时。 
		    rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。 没有默认值,任何异常都回滚。  
		    no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回 滚。没有默认值,任何异常都回滚。  --> 
				<tx:method name="tranfer"/>
			</tx:attributes>
	</tx:advice>
	<!-- 织入 -->
	<aop:config>
		<aop:pointcut expression="execution(* com.it.serviceimpl.TranFerServiceImpl.tranfer(..))" id="pointcut"/>
		<!-- 针对事务的配置标签 -->
		<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut"/>
	</aop:config>
	</beans>
	

test方法

package com.it.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.it.service.TranFerService;
import com.it.serviceimpl.TranFerServiceImpl;

public class TranFerTest {
	public static void main(String[] args) {
		//使用JDK动态代理的方法,使用接口来实现代理,需要使用被代理者来增强
		//使用如果使用CGlib动态代理的方法,只需要使用代理者来增强
		ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
		TranFerService tranferserviceimpl= (TranFerService) context.getBean("tranFerService");
		
		tranferserviceimpl.tranfer("jack","tom",500);
	
	}
}

TranFerService

package com.it.service;

public interface TranFerService {
	public void tranfer(String toUser,String inUser,double Money);
}

TranFerServiceImpl

package com.it.serviceimpl;

import com.it.daoimpl.TranFerDaoImpl;
import com.it.service.TranFerService;

public class TranFerServiceImpl implements TranFerService {
	private TranFerDaoImpl tranFerDao;

	public void setTranFerDao(TranFerDaoImpl tranFerDao) {
		this.tranFerDao = tranFerDao;
	}

	@Override
	public void tranfer(String toUser, String inUser, double Money) {
		//加钱
		tranFerDao.toMoney(toUser,Money);
		//int i=1/0;
		//减钱
		tranFerDao.inMoney(inUser,Money);
		
	}
	
	
}

TranFerDao

package com.it.dao;

public interface TranFerDao {
	public void toMoney(String toUser, double money);
	public void inMoney(String inUser, double money);
}

TranFerDaoImpl

package com.it.daoimpl;

import org.springframework.jdbc.core.JdbcTemplate;

import com.it.dao.TranFerDao;

public class TranFerDaoImpl implements TranFerDao {
	private JdbcTemplate jdbctemplate;

	public void setJdbctemplate(JdbcTemplate jdbctemplate) {
		this.jdbctemplate = jdbctemplate;
	}
	//加钱
	public void toMoney(String toUser, double money) {
		String sql="update atm set money = money + ? where username = ?";
		jdbctemplate.update(sql,money,toUser);		
	}
	//减钱
	public void inMoney(String inUser, double money) {
		String sql="update atm set money = money - ? where username = ?";
		jdbctemplate.update(sql,money,inUser);
		
		
	}
	
}

注解配置: xml+注解(企业开发)
                
               别人的 用xml

              自己的 用注解
                <context:component-scan base-package="com.it"></context:component-scan>

               事务的注解2步:
                    指定开启事务的注解 告诉spirng使用的事务方法是谁的方法
                        <tx:annotation-driven transaction-manager="PlatformTransactionManager"/>

                    在方法上或则是类上配置:
                        @Transactional

jdbc.properties同上

 

bean.xml

配置事务管理器并注入数据源 

 <tx:annotation-driven transaction-manager="PlatformTransactionManager"/>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd">
        <!-- spring加载src下的properties文件 -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
        
   <!-- c3p0 -->
    <bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>
	
	<!-- jdbcTemplate -->
	<bean id="jdbctemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="c3p0"></property>
	</bean>	
	
	<!-- 切面类 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="c3p0"> </property>
	</bean>
	
	<!-- 自己的类 -->
	
	<!-- 开启注解扫描器 -->
	<context:component-scan base-package="com.it"></context:component-scan>

	<!-- 开启事务的注解配置 告诉使用的是哪个类下的事务 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>
	</beans>
	

test方法同上

TranFerService.java同上

TranFerServiceImpl

在业务层使用@Transactional 注解 

该注解的属性和 xml 中的属性含义一致。

该注解可以出现在接口上,类上和方法上。

出现接口上,表示该接口的所有实现类都有事务支持。

出现在类上,表示类中所有方法有事务支持 出现在方法上,表示方法有事务支持。

以上三个位置的优先级:方法>类>接口 

package com.it.serviceimpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.it.daoimpl.TranFerDaoImpl;
import com.it.service.TranFerService;
@Service("tranFerService")
@Transactional
public class TranFerServiceImpl implements TranFerService {
	@Autowired
	private TranFerDaoImpl tranFerDao;

	
	@Override
	public void tranfer(String toUser, String inUser, double Money) {
		//加钱
		tranFerDao.toMoney(toUser,Money);
		int i=1/0;
		//减钱
		tranFerDao.inMoney(inUser,Money);
		
	}
	
	
}

TranFerDao同上

TranFerDaoImpl

package com.it.daoimpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.it.dao.TranFerDao;
@Repository("tranFerDao")
public class TranFerDaoImpl implements TranFerDao {
	@Autowired
	private JdbcTemplate jdbctemplate;

	
	//加钱
	public void toMoney(String toUser, double money) {
		String sql="update atm set money = money + ? where username = ?";
		jdbctemplate.update(sql,money,toUser);		
	}
	//减钱
	public void inMoney(String inUser, double money) {
		String sql="update atm set money = money - ? where username = ?";
		jdbctemplate.update(sql,money,inUser);
		
		
	}
	
}

全注解的方式配置事务(了解即可)
        条件: 需要注解类

        @EnableTransactionManagement 
        // <tx:annotation-driven transaction-manager="platformTransactionManager"/>

        @Qualifier("c3p0") DataSource ds:参数配置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Exception.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值