官方文档
该@Transactional注解的是,指定的接口,类或方法必须具有事务语义的元数据(例如,“调用该方法时启动一个全新的只读事务,悬浮剂任何现有的交易”)。
传播设置是 PROPAGATION_REQUIRED
隔离级别是 ISOLATION_DEFAULT
该事务是读写的。
事务超时默认为基础事务系统的默认超时,如果不支持超时,则默认为none。
任何RuntimeException触发器回滚,任何检查Exception都没有。
PROPAGATION_REQUIRED如果当前没有事务存在,则执行本地事务的本地事务,或者参与为更大范围定义的现有“外部”事务。这是同一线程内公共调用堆栈安排的一个很好的默认值(例如,委托给几个存储库方法的服务外观,其中所有底层资源都必须参与服务级别事务)。
当传播设置为时PROPAGATION_REQUIRED,将为应用设置的每个方法创建逻辑事务范围。每个这样的逻辑事务范围可以单独确定仅回滚状态,外部事务范围在逻辑上独立于内部事务范围。在标准PROPAGATION_REQUIRED行为的情况下,所有这些范围都映射到同一物理事务。因此,内部事务范围中的仅回滚标记集确实会影响外部事务实际提交的机会。
但是,在内部事务作用域设置仅回滚标记的情况下,外部事务尚未决定回滚本身,因此回滚(由内部事务作用域静默触发)是意外的。UnexpectedRollbackException在那一点上抛出相应的对应 物。这是预期的行为,因此事务的调用者永远不会被误导,假设在实际上没有执行提交。因此,如果内部事务(外部调用者不知道)以静默方式将事务标记为仅回滚,则外部调用者仍会调用commit。外部调用者需要接收一个UnexpectedRollbackException以清楚地表明已执行回滚。
PROPAGATION_REQUIRES_NEW与此相反PROPAGATION_REQUIRED,始终对每个受影响的事务范围使用独立的物理事务,从不参与外部范围的现有事务。在这样的安排中,底层资源事务是不同的,因此可以独立地提交或回滚,外部事务不受内部事务的回滚状态的影响,并且内部事务的锁在完成后立即释放。这样一个独立的内部事务也可以声明它自己的隔离级别,超时和只读设置,而不是继承外部事务的特性。
PROPAGATION_NESTED使用具有多个保存点的单个物理事务,它可以回滚到该事务。这种部分回滚允许内部事务作用域触发其作用域的回滚,外部事务能够继续物理事务,尽管已经回滚了一些 *** 作。此设置通常映射到JDBC保存点,因此它仅适用于JDBC资源事务。见春天DataSourceTransactionManager。
理想 *** 作:
The configured profiling aspect starts
配置的性能分析方面开始。
The transactional advice executes
事务建议执行。
The method on the advised object executes
建议对象上的方法执行。
The transaction commits
事务提交。
The profiling aspect reports the exact duration of the whole transactional method invocation
概要分析方面报告整个事务方法调用的确切持续时间。
技术点:springboot + jdbc + test + maven
pomxml添加如下
applicationproperties
Dao层
Server层
测试类
游离不用说,你自己新建对象就是游离态。
持久态,如果你的事务是放在Service层,那么在Service层及以下的方法里,从Session中获取的对象,或者save
persis
update等的对象就是持久态。
托管态,如果你的Service层方法返回一个PO对象,这个对象返回之后肯定是托管态。
如果你的Service层方法接受一个游离态PO对象,然后被save了,Servcie层方法返回后,这个游离态PO对象,肯定也是托管态。
懒加载异常:
如果你在Action层或者View层对托管态对象调用get方法试图获取懒加载的数据,肯定报异常。
原因是事务边界就在Service层方法处结束,Session也会在Service方法退出后关闭。
而如果使用OpenSessionInViewFilter,则Session的关闭时机会延迟到View层,其实就是JSP代码运行完毕之后才关闭。这样的话就不会报懒加载异常了。
继续验证,这次的主角是
@Transactional(propagation= PropagationSUPPORTS)
它总是使用调用者事务,若调用者没事务则以无事务状态执行
两者均以无事务的状态运行
两者均以无事务的状态运行
两者均以无事务的状态运行
报异常
报异常
InsertUser 非事务方式执行,InsertCuser 创建了事务
InsertUser 将事务传播给InsertCuser ,两者使用同一事务
两者均以无事务的状态运行
两者均以无事务的状态运行
两者均以无事务的状态运行
两者均以无事务的状态运行
InsertUser 非事务方式执行,InsertCuser 创建了事务
InsertUser 将事务传播给InsertCuser ,两者使用同一事务
继续第三篇
>
Spring+Hibernate的实质:
就是把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理。
那么再没整合之前Hibernate是如何实现事务管理的呢?
通过ServletFilter实现数据库事务的管理,这样就避免了在数据库 *** 作中每次都要进行数据库事务处理。
一事务的4个特性:
原子性:一个事务中所有对数据库的 *** 作是一个不可分割的 *** 作序列,要么全做,要么全部做。
一致性:数据不会因为事务的执行而遭到破坏。
隔离性:一个事务的执行,不受其他事务(进程)的干扰。既并发执行的个事务之间互不干扰。
持久性:一个事务一旦提交,它对数据库的改变将是永久的。
二事务的实现方式:
实现方式共有两种:编码方式;声明式事务管理方式。
基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。
声明式事务管理又有两种方式:基于XML配置文件的方式;另一个是在业务方法上进行@Transactional注解,将事务规则应用到业务逻辑中。
三创建事务的时机:
是否需要创建事务,是由事务传播行为控制的。读数据不需要或只为其指定只读事务,而数据的插入,修改,删除就需要事务管理了。
一种常见的事务管理配置:事务拦截器TransactionInterceptor和事务自动代理BeanNameAutoProxyCreator相结合的方式
<!--定义Hibernate的事务管理器HibernateTransactionManager -->
<bean id="transactionManager"
class="orgspringframeworkormhibernate3HibernateTransactionManager">
<!-- 依赖注入上面定义的sessionFactory -->
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--定义Spring的事务拦截器TransactionInterceptor -->
<bean id="transactionInterceptor" class="orgspringframeworktransactioninterceptorTransactionInterceptor">
<!-- 依赖注入上面定义的事务管理器transactionManager -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 定义需要进行事务拦截的方法及所采用的事务控制类型 -->
<property name="transactionAttributes">
<props>
<!-- 以browse、list、load、get及is开头的所有方法采用只读型事务控制类型 -->
<prop key="browse">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="is">PROPAGATION_REQUIRED,readOnly</prop>
<!-- 所有方法均进行事务控制,如果当前没有事务,则新建一个事务 -->
<prop key="">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定义BeanNameAutoProxyCreatorf进行Spring的事务处理-->
<bean class="orgspringframeworkaopframeworkautoproxyBeanNameAutoProxyCreator">
<!-- 针对指定的bean自动生成业务代理 -->
<property name="beanNames">
<list>
<value>adminService</value>
<value>columnsService</value>
<value>newsService</value>
<value>crawlService</value>
<value>memberLevelService</value>
<value>memberService</value>
<value>categoryService</value>
<value>merService</value>
<value>cartService</value>
<value>ordersService</value>
<value>trafficService</value>
</list>
</property>
<!-- 这个属性为true时,表示被代理的是目标类本身而不是目标类的接口 -->
<property name="proxyTargetClass">
<value>true</value>
</property>
<!-- 依赖注入上面定义的事务拦截器transactionInterceptor -->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
尤其注意:如下
以上的事务拦截器和事务自动代理方式实现原理:像Struts2一样,都是凭借强大的拦截器功能对业务逻辑方法的调用进行拦截,然后又BeanNameAutoProxyCreator自动生成事务代理,最后送事务管理器,统一管理
Spring+Hibernate的实质:
就是把Hibernate用到的数据源Datasource,Hibernate的SessionFactory实例,事务管理器HibernateTransactionManager,都交给Spring管理。
那么再没整合之前Hibernate是如何实现事务管理的呢?
通过ServletFilter实现数据库事务的管理,这样就避免了在数据库 *** 作中每次都要进行数据库事务处理。
一事务的4个特性:
原子性:一个事务中所有对数据库的 *** 作是一个不可分割的 *** 作序列,要么全做,要么全部做。
一致性:数据不会因为事务的执行而遭到破坏。
隔离性:一个事务的执行,不受其他事务(进程)的干扰。既并发执行的个事务之间互不干扰。
持久性:一个事务一旦提交,它对数据库的改变将是永久的。
二事务的实现方式:
实现方式共有两种:编码方式;声明式事务管理方式。
基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务。
声明式事务管理又有两种方式:基于XML配置文件的方式;另一个是在业务方法上进行@Transactional注解,将事务规则应用到业务逻辑中。
三创建事务的时机:
是否需要创建事务,是由事务传播行为控制的。读数据不需要或只为其指定只读事务,而数据的插入,修改,删除就需要事务管理了。
一种常见的事务管理配置:事务拦截器TransactionInterceptor和事务自动代理BeanNameAutoProxyCreator相结合的方式
<!--定义Hibernate的事务管理器HibernateTransactionManager -->
<bean id="transactionManager"
class="orgspringframeworkormhibernate3HibernateTransactionManager">
<!-- 依赖注入上面定义的sessionFactory -->
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--定义Spring的事务拦截器TransactionInterceptor -->
<bean id="transactionInterceptor" class="orgspringframeworktransactioninterceptorTransactionInterceptor">
<!-- 依赖注入上面定义的事务管理器transactionManager -->
<property name="transactionManager" ref="transactionManager"/>
<!-- 定义需要进行事务拦截的方法及所采用的事务控制类型 -->
<property name="transactionAttributes">
<props>
<!-- 以browse、list、load、get及is开头的所有方法采用只读型事务控制类型 -->
<prop key="browse">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="is">PROPAGATION_REQUIRED,readOnly</prop>
<!-- 所有方法均进行事务控制,如果当前没有事务,则新建一个事务 -->
<prop key="">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定义BeanNameAutoProxyCreatorf进行Spring的事务处理-->
<bean class="orgspringframeworkaopframeworkautoproxyBeanNameAutoProxyCreator">
<!-- 针对指定的bean自动生成业务代理 -->
<property name="beanNames">
<list>
<value>adminService</value>
<value>columnsService</value>
<value>newsService</value>
<value>crawlService</value>
<value>memberLevelService</value>
<value>memberService</value>
<value>categoryService</value>
<value>merService</value>
<value>cartService</value>
<value>ordersService</value>
<value>trafficService</value>
</list>
</property>
<!-- 这个属性为true时,表示被代理的是目标类本身而不是目标类的接口 -->
<property name="proxyTargetClass">
<value>true</value>
</property>
<!-- 依赖注入上面定义的事务拦截器transactionInterceptor -->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
尤其注意:如下
以上的事务拦截器和事务自动代理方式实现原理:像Struts2一样,都是凭借强大的拦截器功能对业务逻辑方法的调用进行拦截,然后又BeanNameAutoProxyCreator自动生成事务代理,最后送事务管理器,统一管理
利用线程池和CountDownLatch,多线程并发处理批量数据,实现多线程事务回滚,事务补偿。
begin设置为1,用于发布开始命令,如果需要开始,则begincountdown
end用于记录任务的执行情况。begincountdown后,需endawait,等待任务都执行完。
当begincountdown开始执行任务后,在最后需endcountdown
当endcountdown减到为0后,则切换到主线程,继续开始往下执行
实现更灵活的去配置各业务数据 *** 作场景,即:暴露excute方法执行线程任务,执行的具体执行任务交给回调函数实现。
基于spring上下文中获取事务管理器
封装获取spring上下文工具类
ApplicationContextProvider
以上就是关于Spring本地事务全部的内容,包括:Spring本地事务、JAVA Spring与事务, 三种时态(游离/托管/持久), 懒加载的关系、spring 事务管理之事务传播行为之实践SUPPORTS(二)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)