Spring中的事务属性介绍以及声明式事务管理

news/2024/5/18 15:09:06 标签: spring, dao, class, aop, attributes, jdbc
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

 class="hilite1">Spring 中的事务管理主要有编程式事务管理和声明式事务管理,这里主要介绍声明式事务管理。在class="hilite1">Spring 中,主要是通过AOP来完成声明式的事务管理。要了解class="hilite1">Spring 对事务的支持,首先要了解事务的属性。在class="hilite1">Spring 中事务属性主要分以下几方面:
    1、传播行为(Propagation behavior)
       可以找到相对应的常数与说明,列出下列几个:
       PROPAGATION_MANDATORY:方法必须在一个现存的事务中进行,否则丢出异常
       PROPAGATION_NESTED:在一个嵌入的事务中进行
       PROPAGATION_NEVER:不应在事务中进行,如果有则丢异常
       PROPAGATION_NOT_SUPPORTED:不应再事务中进行,如果有就暂停现存的事务
       PROPAGATION_REQUIRED:支持现在的事务,如果没有就建立一个新的事务
       PROPAGATION_REQUIRES_NEW:建立一个新的事务,如果现存一个事务就暂停它
       PROPAGATION_SUPPORTS:支持现在的事务,如果没有就以非事务的方式执行
   
    2、隔离层级(Isolation level)
       在一个应用程序中,可能有多个事务在同时进行,这些事务应当彼此之间互不知道另一个事务的存在,比如现在整个应用程序就只有一个事务存在,由于事务彼此之间独立,若读取的是同一个数据的话,就容易发生问题,比如:
       Dirty read(脏读):某个事务已经更新了一份数据,另一份事务在此时读取了同一份数据,由于某些原因,前一个事务回滚了,则后一个事务读取的数据则是错误的。
       Non-repeatable read(非重复读):在一个事务的两次查询中事务不一致,可能是因为两次查询过程中间插入了一个事务更新的原有数据。
       Phantom read(幻象读):在一个事务的两次查询中数据笔数不一致。

解决以上问题的方法之一,就是在某个事务进行过程中锁定正在更新或查询的数据,但是这样会造成效率上的问题,别的事务必须等待当前事务解锁后才能进行。然而,根据需求的不同,并不用在事务进行时完全的锁定数据,隔离层级可以让您根据实际的需求,对数据的锁定进行设置。一下是几个隔离层级的参数说明:

       ISOLATION_DEFAULT:使用底层数据库预设的隔离层级
       ISOLATION_READ_COMMITTED:运行事务读取其他事务已经提交的数据字段,可以防止脏读问题
       ISOLATION_READ_UNCOMMITTED:运行事务读取其他并行事务还没有提交的数据,会发生脏读、非重复读、幻象读等问题
       ISOLATION_REPEATABLE_READ:要求多次读取的数据必须相同,除非事务本身更新数据,可以防止脏读、非重复读等问题
       ISOLATION_SERIALIZABLE:完整的隔离层级,防止所有问题,会锁定数据对应的表,有效率问题

事实上,对于事务的传播特性,可以设置对应的隔离层级。在class="hilite1">Spring 中,我们用的最多的就是PROPAGATIOIN_REQUIRED这种传播行为。这个意思是,如果应用程序中已经存在一个事务了,当另一个事务进来时,会加入到这个事务中,如果没有事务存在,则开启一个新的事务。

请看一下对事务传播特性设置的配置文件

class="dp-highlighter">
class="bar">
class="tools"> Java代码 复制代码
    class="dp-j">
  1. <?xml version=class="string">"1.0"  encoding=class="string">"UTF-8" ?>   
  2.   
  3. <beans xmlns=class="string">"http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans"   
  4.         xmlns:xsi=class="string">"http://www.w3.org/2001/XMLSchema-instance"   
  5.         xmlns:aop=class="string">"http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop"   
  6.         xmlns:tx=class="string">"http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx"   
  7.         xsi:schemaLocation="   
  8.             http:class="comment">//www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring -beans-2.5.xsd   
  9.             http:class="comment">//www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring -aop-2.5.xsd   
  10.             http:class="comment">//www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring -tx-2.5.xsd">   
  11.   
  12.     <bean id=class="string">"sessionFactory"  class="keyword">class =class="string">"org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.LocalSessionFactoryBean" >   
  13.         <property name=class="string">"configLocation" >   
  14.             <value>classpath:hibernate.cfg.xml</value>   
  15.         </property>      
  16.     </bean>   
  17.        
  18.     <bean id=class="string">"transactionManager"  class="keyword">class =class="string">"org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.HibernateTransactionManager" >   
  19.         <property name=class="string">"sessionFactory"  ref=class="string">"sessionFactory"  />   
  20.     </bean>   
  21.        
  22.     <tx:advice id=class="string">"txAdvice"  transaction-manager=class="string">"transactionManager" >   
  23.         <tx:attributes>   
  24.             <tx:method name=class="string">"insert*"  propagation=class="string">"REQUIRED"  />   
  25.             <tx:method name=class="string">"del*"  propagation=class="string">"REQUIRED" />   
  26.             <tx:method name=class="string">"update*"  propagation=class="string">"REQUIRED" />   
  27.             <tx:method name=class="string">"*"  read-only=class="string">"true" />   
  28.         </tx:attributes>   
  29.     </tx:advice>    
  30.        
  31.     <aop:config>   
  32.         <aop:pointcut id=class="string">"allDaoMethod"  expression=class="string">"execution (* org.whatisjava.class="tags" href="/tags/DAO.html" title=dao>dao..*.*(..))" />   
  33.         <aop:advisor advice-ref=class="string">"txAdvice"  pointcut-ref=class="string">"allDaoMethod" />   
  34.     </aop:config>   
  35.     </beans>  
class="language-java"><?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop"
		xmlns:tx="http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring
-beans-2.5.xsd
			http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring
-aop-2.5.xsd
			http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring
-tx-2.5.xsd">

	<bean id="sessionFactory" class="org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>	
	</bean>
	
	<bean id="transactionManager" class="org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="del*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="*" read-only="true"/>
		</tx:attributes>
	</tx:advice> 
	
	<aop:config>
		<aop:pointcut id="allDaoMethod" expression="execution (* org.whatisjava.class="tags" href="/tags/DAO.html" title=dao>dao..*.*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="allDaoMethod"/>
	</aop:config>
	</beans>


       
在<tx:method>中的属性设置,对于传播行为、隔离层级、只读、超时等,都有对应的"propagation"、"isolation"、"timeout"、"read-only"等等,这里设置的传播属性是"REQUIRED",则它对应的默认的隔离层级就是"DEFAULT","timeout"默是"-1","read-only"默认是"false"。我们也可以根据这些参数来选取不同的参数设置,比如

class="dp-highlighter">
class="bar">
class="tools"> Java代码 复制代码
    class="dp-j">
  1. ...   
  2. <tx:advice id=class="string">"txAdvice"  transaction-manager=class="string">"transactionManager" >   
  3.         <tx:attributes>   
  4.             <tx:method name=class="string">"insert*"  propagation=class="string">"REQUIRED"  isolation=class="string">"SERIALIZABLE" />   
  5.             <tx:method name=class="string">"del*"  propagation=class="string">"REQUIRED"  isolation=class="string">"SERIALIZABLE" />   
  6.             <tx:method name=class="string">"update*"  propagation=class="string">"REQUIRED"  isolation=class="string">"SERIALIZABLE" />   
  7.             <tx:method name=class="string">"*"  read-only=class="string">"true" />   
  8.         </tx:attributes>   
  9.     </tx:advice>    
  10. ....  
class="language-java">...
<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="insert*" propagation="REQUIRED" isolation="SERIALIZABLE"/>
			<tx:method name="del*" propagation="REQUIRED" isolation="SERIALIZABLE"/>
			<tx:method name="update*" propagation="REQUIRED" isolation="SERIALIZABLE"/>
			<tx:method name="*" read-only="true"/>
		</tx:attributes>
	</tx:advice> 
....




这是基于xml配置文件进行的事务属性的传播控制,也可以基于注解方式的,请看如下代码

class="dp-highlighter">
class="bar">
class="tools"> Java代码 复制代码
    class="dp-j">
  1. class="keyword">package  org.whatisjava.class="tags" href="/tags/DAO.html" title=dao>dao.impl;   
  2.   
  3. class="keyword">import  java.util.List;   
  4.   
  5. class="keyword">import  org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.support.HibernateDaoSupport;   
  6. class="keyword">import  org.class="tags" href="/tags/SPRING.html" title=spring>springframework.transaction.annotation.Propagation;   
  7. class="keyword">import  org.class="tags" href="/tags/SPRING.html" title=spring>springframework.transaction.annotation.Transactional;   
  8. class="keyword">import  org.whatisjava.class="tags" href="/tags/DAO.html" title=dao>dao.UserDao;   
  9. class="keyword">import  org.whatisjava.po.User;   
  10.   
  11. class="keyword">public  class="keyword">class  UserDaoBean class="keyword">extends  HibernateDaoSupport class="keyword">implements  UserDao {   
  12.   
  13.     class="annotation">@Transactional (propagation = Propagation.REQUIRED)   
  14.     class="keyword">public  class="keyword">void  delUser(Integer id) {   
  15.         getHibernateTemplate().delete((User)getHibernateTemplate().get(User.class="keyword">class , id));   
  16.     }   
  17.   
  18.     class="annotation">@Transactional (readOnly = class="keyword">true )   
  19.     class="keyword">public  User findUser(Integer id) {   
  20.         class="keyword">return  (User)getHibernateTemplate().get(User.class="keyword">class , id);   
  21.     }   
  22.   
  23.     class="annotation">@Transactional (propagation = Propagation.REQUIRED)   
  24.     class="keyword">public  class="keyword">void  insertUser(User user) {   
  25.         getHibernateTemplate().save(user);   
  26.     }   
  27.   
  28.     class="annotation">@Transactional (readOnly = class="keyword">true )   
  29.     class="keyword">public  List listUser() {   
  30.         class="keyword">return  getHibernateTemplate().find(class="string">"from User user" );   
  31.     }   
  32.   
  33.     class="annotation">@Transactional (propagation = Propagation.REQUIRED)   
  34.     class="keyword">public  class="keyword">void  updateUser(User user) {   
  35.         getHibernateTemplate().update(user);   
  36.     }   
  37.   
  38. }  
class="language-java">package org.whatisjava.class="tags" href="/tags/DAO.html" title=dao>dao.impl;

import java.util.List;

import org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.class="tags" href="/tags/SPRING.html" title=spring>springframework.transaction.annotation.Propagation;
import org.class="tags" href="/tags/SPRING.html" title=spring>springframework.transaction.annotation.Transactional;
import org.whatisjava.class="tags" href="/tags/DAO.html" title=dao>dao.UserDao;
import org.whatisjava.po.User;

public class UserDaoBean extends HibernateDaoSupport implements UserDao {

	@Transactional(propagation = Propagation.REQUIRED)
	public void delUser(Integer id) {
		getHibernateTemplate().delete((User)getHibernateTemplate().get(User.class, id));
	}

	@Transactional(readOnly = true)
	public User findUser(Integer id) {
		return (User)getHibernateTemplate().get(User.class, id);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void insertUser(User user) {
		getHibernateTemplate().save(user);
	}

	@Transactional(readOnly = true)
	public List listUser() {
		return getHibernateTemplate().find("from User user");
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void updateUser(User user) {
		getHibernateTemplate().update(user);
	}

}



要想让这些注解配置生效,必须在配置文件里加入最后一行

class="dp-highlighter">
class="bar">
class="tools"> Java代码 复制代码
    class="dp-j">
  1. <?xml version=class="string">"1.0"  encoding=class="string">"UTF-8" ?>   
  2.   
  3. <beans xmlns=class="string">"http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans"   
  4.         xmlns:xsi=class="string">"http://www.w3.org/2001/XMLSchema-instance"   
  5.         xmlns:aop=class="string">"http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop"   
  6.         xmlns:tx=class="string">"http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx"   
  7.         xsi:schemaLocation="   
  8.             http:class="comment">//www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring -beans-2.5.xsd   
  9.             http:class="comment">//www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring -aop-2.5.xsd   
  10.             http:class="comment">//www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring -tx-2.5.xsd">   
  11.   
  12.     <bean id=class="string">"sessionFactory"  class="keyword">class =class="string">"org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.LocalSessionFactoryBean" >   
  13.         <property name=class="string">"configLocation" >   
  14.             <value>classpath:hibernate.cfg.xml</value>   
  15.         </property>      
  16.     </bean>   
  17.        
  18.     <bean id=class="string">"transactionManager"  class="keyword">class =class="string">"org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.HibernateTransactionManager" >   
  19.         <property name=class="string">"sessionFactory"  ref=class="string">"sessionFactory"  />   
  20.     </bean>   
  21.        
  22. <tx:annotation-driven transaction-manager=class="string">"transactionManager" />   
  23. </beans>  
class="language-java"><?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop"
		xmlns:tx="http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/beans/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring
-beans-2.5.xsd
			http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/aop/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring
-aop-2.5.xsd
			http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx http://www.class="tags" href="/tags/SPRING.html" title=spring>springframework.org/schema/tx/class="hilite1">class="tags" href="/tags/SPRING.html" title=spring>spring
-tx-2.5.xsd">

	<bean id="sessionFactory" class="org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation">
			<value>classpath:hibernate.cfg.xml</value>
		</property>	
	</bean>
	
	<bean id="transactionManager" class="org.class="tags" href="/tags/SPRING.html" title=spring>springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
	
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>


     
好了,以上就是class="hilite1">Spring 中的事务属性的介绍,以及class="hilite1">Spring 中如何以声明方式管理事务的。



()

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

附:
jquery中jquery对象取某元素的某属性:
$(obj).attr("xxx")
jquery对象获得dom对象 $(obj).obj()
this一般是dom对象,若要jquery对象则$(this)


()

浅析Spring提供的事务管理方法

2006-03-02 08:32作者:fly29出处:blog责任编辑:方舟
class="topadbg">
class="guanggao">
  Spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;而声明式的比编程式的更灵活方便。本文将讨论这两种事务管理的区别。

  传统的JDBC事务管理

  以往使用JDBC进行数据操作时,一般采用DataSource,从数据源中得到Connection,我们知道数据源是线程安全的,而连接不是线程安全的,所以对每个请求都是从数据源中重新取出一个连接。一般的数据源由容器进行管理,包括连接池。例如TOMCAT,WEBSPHERE,WEBLOGIC等这些J2EE商业容器都提供了这个功能。

  以往的我们使用JDBC在写代码时,事务管理可能会是这样:

Connection conn = null;
try
{
 conn = DBConnectionFactory.getConnection;
 conn.setAutoCommit(false);
 //do something
 conn.commit(); //commit transcation
}
catch(Exception e)
{
 conn.rollback();
 //do sth
}
finally
{
 try
 {
  conn.close();
 }
 catch(SQLException se){ //do sth.}
 //close ResultSet,PreparedStatement,Connection
 //notice:Maybe ocurr Exception when u close rs,pstmt,conn
}

  按照以往的思路来写代码,代码量比较长,而且容易疏忽,忘掉一些try/catch,引发一些异常无法catch,虽然有时候我们会写DBTool类,来关闭这些资源,并且保证在关闭这些资源时,不向外抛异常。

  Spring提供的编程式的事务处理

  Spring提供了几个关于事务处理的类:

  ·TransactionDefinition //事务属性定义
  ·TranscationStatus //代表了当前的事务,可以提交,回滚。
  ·PlatformTransactionManager这个是class="tags" href="/tags/SPRING.html" title=spring>spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。

  我们使用编程式的事务管理流程可能如下:

  1 声明数据源

  2 声明一个事务管理类,例如DataSourceTransactionManager,HibernateTransactionManger,JTATransactionManager等

  3 在我们的代码中加入事务处理代码:

TransactionDefinition td = new TransactionDefinition();
TransactionStatus ts = transactionManager.getTransaction(td);
try
{
 //do sth
 transactionManager.commit(ts);
}
catch(Exception e){transactionManager.rollback(ts);}

  使用class="tags" href="/tags/SPRING.html" title=spring>spring提供的事务模板TransactionTemplate

void add()
{
 transactionTemplate.execute( new TransactionCallback(){
  pulic Object doInTransaction(TransactionStatus ts)
  { //do sth}
 }
}

  TransactionTemplate也是为我们省去了部分事务提交、回滚代码;定义事务模板时,需注入事务管理对象.

  Spring声明式事务处理

  Spring声明式事务处理也主要使用了ioc,aop思想,提供了TransactionInterceptor拦截器和常用的代理类TransactionProxyFactoryBean,可以直接对组件进行事务代理。

  使用TransactionInterceptor步骤

  1.定义数据源,事务管理类

  2.定义事务拦截器,such as:

<bean id = "transactionInterceptor" class="org.class="tags" href="/tags/SPRING.html" title=spring>springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributeSource">
<value>
com.test.UserManager.*r=PROPAGATION_REQUIRED
</value>
</property>
</bean>

  3.为组件声明一个代理类:ProxyFactoryBean

<bean id="userManager" class="org.class="tags" href="/tags/SPRING.html" title=spring>springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.test.UserManager</value></property>
<property name="interceptorNames">
<list>
<idref local="transactionInterceptor"/>
</list>
</property>
</bean>

  使用TransactionProxyFactoryBean:

<bean id="userManager" class="org.class="tags" href="/tags/SPRING.html" title=spring>springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="target"><ref local="userManagerTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>

  TransactionProxyFactoryBean只是为组件的事务代理,如果我们要给组件添加一些业务方面的验证等,可以使用TransactionTemplate加拦截器方式,为组件添加多个拦截器,class="tags" href="/tags/SPRING.html" title=spring>spring AOP中提供了三类Advice,即前增强,后增强,抛出异常时的增强,可以灵活使用。

()
va Application以及所需要的数据库和数据表,本节将介绍JOTM在Spring中的配置。


JOTM(Java Open
class="hilite3">Transaction Manager)是ObjectWeb的一个开源class="hilite4">JTA 实现,本身也是开源应用程序服务器 JOnAS(Java Open Application Server)的一部分,为其提供class="hilite4">JTA 分 布式事务的功能。Spring对JOTM提供了较好的支持,提供了一个class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite3">transaction .class="hilite4">jta .JotmFactoryBean的支持类,在Spring2.0中也包含了JOTM相关的一些 library。

jotm的下载地址为http://jotm.objectweb.
class="hilite1">org ,最新版 本为2.0.10.

下载完成后解压缩,然后打开jotm下面conf文件夹,拷贝carol.properties文件到classpath中,并修改这个文件如下

carol.properties
class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. class="keyword">do  not use CAROL JNDI wrapper     
  2. carol.start.jndi=class="keyword">false      
  3.      
  4. class="keyword">do  not start a name server     
  5. carol.start.ns=class="keyword">false      
  6.      
  7. # Naming Factory  
  8. carol.jndi.java.naming.factory.url.pkgs=class="hilite1">org .apache.naming  
class="language-java"># do not use CAROL JNDI wrapper   
carol.start.jndi=false   
   
# do not start a name server   
carol.start.ns=false   
   
# Naming Factory
carol.jndi.java.naming.factory.url.pkgs=class="hilite1">org
.apache.naming

上面配置文件的目的是不使用JNDI的方式来加载JOTM的配置,当然也可以根据需要选择其它的一些配置,例如JTOM所提供的默认配置。

然后开始在Spring上下文中配置JOTM,在classpath中建立一个ApplicationContext-jotm.xml,配置如 下


ApplicationContext-jotm.xml

class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. <?xml version=class="string">"1.0"  encoding=class="string">"UTF-8" ?>  
  2. <beans xmlns=class="string">"http://www.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite1">org /schema/beans"   
  3.     xmlns:xsi=class="string">"http://www.w3.class="hilite1">org /2001/XMLSchema-instance"   
  4.     xsi:schemaLocation=class="string">"http://www.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite1">org /schema/beans http://www.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite1">org /schema/beans/class="tags" href="/tags/SPRING.html" title=spring>spring-beans-2.0.xsd" >  
  5.   
  6.     <bean id=class="string">"jotm"  class="keyword">class =class="string">"class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite3">transaction .class="hilite4">jta .JotmFactoryBean" />  
  7.       
  8.     <bean id=class="string">"txManager"  class="keyword">class =class="string">"class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite3">transaction .class="hilite4">jta .JtaTransactionManager" >  
  9.         <property name=class="string">"userTransaction"  ref=class="string">"jotm"  />  
  10.     </bean>  
  11.   
  12.     <bean id=class="string">"ds1"  class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.pool.StandardXAPoolDataSource"  destroy-method=class="string">"shutdown" >  
  13.         <property name=class="string">"dataSource" >  
  14.             <bean class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.standard.StandardXADataSource"  destroy-method=class="string">"shutdown" >  
  15.                 <property name=class="string">"transactionManager"  ref=class="string">"jotm"  />  
  16.                 <property name=class="string">"driverName"  value=class="string">"com.mysql.jdbc.Driver"  />  
  17.                 <property name=class="string">"url"  value=class="string">"jdbc:MySQL://localhost:3306/test"  />  
  18.             </bean>  
  19.         </property>  
  20.         <property name=class="string">"user"  value=class="string">"root"  />  
  21.         <property name=class="string">"password"  value=class="string">"admin"  />  
  22.     </bean>  
  23.       
  24.     <bean id=class="string">"ds2"  class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.pool.StandardXAPoolDataSource"  destroy-method=class="string">"shutdown" >  
  25.         <property name=class="string">"dataSource" >  
  26.             <bean class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.standard.StandardXADataSource"  destroy-method=class="string">"shutdown" >  
  27.                 <property name=class="string">"transactionManager"  ref=class="string">"jotm"  />  
  28.                 <property name=class="string">"driverName"  value=class="string">"com.mysql.jdbc.Driver"  />  
  29.                 <property name=class="string">"url"  value=class="string">"jdbc:MySQL://localhost:3306/test2"  />  
  30.             </bean>  
  31.         </property>  
  32.         <property name=class="string">"user"  value=class="string">"root"  />  
  33.         <property name=class="string">"password"  value=class="string">"admin"  />  
  34.     </bean>  
  35.   
  36.     <bean id=class="string">"template1"  class="keyword">class =class="string">"class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .jdbc.core.JdbcTemplate" >  
  37.         <property name=class="string">"dataSource"  ref=class="string">"ds1"  />  
  38.     </bean>  
  39.       
  40.     <bean id=class="string">"template2"  class="keyword">class =class="string">"class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .jdbc.core.JdbcTemplate" >  
  41.         <property name=class="string">"dataSource"  ref=class="string">"ds2"  />  
  42.     </bean>  
  43.       
  44.     <bean id=class="string">"class="tags" href="/tags/DAO.html" title=dao>dao1"  class="keyword">class =class="string">"com.xa.class="tags" href="/tags/DAO.html" title=dao>dao.UserDao1" >  
  45.         <property name=class="string">"jdbcTemplate" >  
  46.             <ref bean=class="string">"template1" ></ref>  
  47.         </property>  
  48.     </bean>  
  49.       
  50.     <bean id=class="string">"class="tags" href="/tags/DAO.html" title=dao>dao2"  class="keyword">class =class="string">"com.xa.class="tags" href="/tags/DAO.html" title=dao>dao.UserDao2" >  
  51.         <property name=class="string">"jdbcTemplate" >  
  52.             <ref bean=class="string">"template2" ></ref>  
  53.         </property>  
  54.     </bean>  
  55.       
  56.     <bean id=class="string">"userServiceTarget"  class="keyword">class =class="string">"com.xa.service.UserServiceImpl" >  
  57.         <property name=class="string">"class="tags" href="/tags/DAO.html" title=dao>dao1"  ref=class="string">"class="tags" href="/tags/DAO.html" title=dao>dao1" />  
  58.         <property name=class="string">"class="tags" href="/tags/DAO.html" title=dao>dao2"  ref=class="string">"class="tags" href="/tags/DAO.html" title=dao>dao2" />  
  59.     </bean>  
  60.   
  61.   
  62.     <bean id=class="string">"userTest"  class="keyword">class =class="string">"class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite3">transaction .interceptor.TransactionProxyFactoryBean" >      
  63.         <property name=class="string">"transactionManager" >  
  64.             <ref bean=class="string">"txManager" />  
  65.         </property>      
  66.         <property name=class="string">"target" >  
  67.             <ref bean=class="string">"userServiceTarget" />  
  68.         </property>  
  69.         <property name=class="string">"transactionAttributes" >          
  70.             <props>  
  71.                 <prop key=class="string">"insert*" >PROPAGATION_REQUIRED,-Exception</prop>              
  72.             </props>  
  73.         </property>  
  74.     </bean>  
  75. </beans>  
class="language-java"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite1">org
/schema/beans"
    xmlns:xsi="http://www.w3.class="hilite1">org
/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite1">org
/schema/beans http://www.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite1">org
/schema/beans/class="tags" href="/tags/SPRING.html" title=spring>spring-beans-2.0.xsd">

	<bean id="jotm" class="class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite3">transaction
.class="hilite4">jta
.JotmFactoryBean"/>
	
	<bean id="txManager" class="class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite3">transaction
.class="hilite4">jta
.JtaTransactionManager">
		<property name="userTransaction" ref="jotm" />
	</bean>

	<bean id="ds1" class="class="hilite1">org
.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
		<property name="dataSource">
			<bean class="class="hilite1">org
.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
				<property name="transactionManager" ref="jotm" />
				<property name="driverName" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:MySQL://localhost:3306/test" />
			</bean>
		</property>
		<property name="user" value="root" />
		<property name="password" value="admin" />
	</bean>
	
	<bean id="ds2" class="class="hilite1">org
.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
		<property name="dataSource">
			<bean class="class="hilite1">org
.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
				<property name="transactionManager" ref="jotm" />
				<property name="driverName" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:MySQL://localhost:3306/test2" />
			</bean>
		</property>
		<property name="user" value="root" />
		<property name="password" value="admin" />
	</bean>

	<bean id="template1" class="class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="ds1" />
	</bean>
	
	<bean id="template2" class="class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="ds2" />
	</bean>
	
	<bean id="class="tags" href="/tags/DAO.html" title=dao>dao1" class="com.xa.class="tags" href="/tags/DAO.html" title=dao>dao.UserDao1">
		<property name="jdbcTemplate">
			<ref bean="template1"></ref>
		</property>
	</bean>
	
	<bean id="class="tags" href="/tags/DAO.html" title=dao>dao2" class="com.xa.class="tags" href="/tags/DAO.html" title=dao>dao.UserDao2">
		<property name="jdbcTemplate">
			<ref bean="template2"></ref>
		</property>
	</bean>
	
	<bean id="userServiceTarget" class="com.xa.service.UserServiceImpl">
		<property name="class="tags" href="/tags/DAO.html" title=dao>dao1" ref="class="tags" href="/tags/DAO.html" title=dao>dao1"/>
		<property name="class="tags" href="/tags/DAO.html" title=dao>dao2" ref="class="tags" href="/tags/DAO.html" title=dao>dao2"/>
	</bean>


	<bean id="userTest" class="class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite3">transaction
.interceptor.TransactionProxyFactoryBean">    
		<property name="transactionManager">
			<ref bean="txManager"/>
		</property>    
		<property name="target">
			<ref bean="userServiceTarget"/>
		</property>
		<property name="transactionAttributes">        
			<props>
				<prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop>            
			</props>
		</property>
	</bean>
</beans>

上面是一个完整的Spring上下文配置,可以看第一个bean “jotm”,实际上引用了Spring内部所提供的对JOTM支持的工厂类,参考下面的配置代码段
class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. <bean id=class="string">"jotm"  class="keyword">class =class="string">"class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite3">transaction .class="hilite4">jta .JotmFactoryBean" />  
class="language-java"><bean id="jotm" class="class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite3">transaction
.class="hilite4">jta
.JotmFactoryBean"/>


随后,配置了
class="hilite4">JTA 事务管理器,并且在管理器中使用上面所配置的jotm,如下面的 代码
class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. <bean id=class="string">"txManager"  class="keyword">class =class="string">"class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .class="hilite3">transaction .class="hilite4">jta .JtaTransactionManager" >  
  2.     <property name=class="string">"userTransaction"  ref=class="string">"jotm"  />  
  3. </bean>  
class="language-java"><bean id="txManager" class="class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.class="hilite3">transaction
.class="hilite4">jta
.JtaTransactionManager">
	<property name="userTransaction" ref="jotm" />
</bean>


再接下来就是配置多个数据源了,使用jotm提供的
class="hilite1">org .enhydra.jdbc.pool.StandardXAPoolDataSource 类,根据类名可以明确地看出它是用以配置多个数据源的啦,配置的代码如下
class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. <bean id=class="string">"ds1"  class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.pool.StandardXAPoolDataSource"  destroy-method=class="string">"shutdown" >  
  2.         <property name=class="string">"dataSource" >  
  3.             <bean class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.standard.StandardXADataSource"  destroy-method=class="string">"shutdown" >  
  4.                 <property name=class="string">"transactionManager"  ref=class="string">"jotm"  />  
  5.                 <property name=class="string">"driverName"  value=class="string">"com.mysql.jdbc.Driver"  />  
  6.                 <property name=class="string">"url"  value=class="string">"jdbc:MySQL://localhost:3306/test"  />  
  7.             </bean>  
  8.         </property>  
  9.         <property name=class="string">"user"  value=class="string">"root"  />  
  10.         <property name=class="string">"password"  value=class="string">"admin"  />  
  11.     </bean>  
  12.       
  13.     <bean id=class="string">"ds2"  class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.pool.StandardXAPoolDataSource"  destroy-method=class="string">"shutdown" >  
  14.         <property name=class="string">"dataSource" >  
  15.             <bean class="keyword">class =class="string">"class="hilite1">org .enhydra.jdbc.standard.StandardXADataSource"  destroy-method=class="string">"shutdown" >  
  16.                 <property name=class="string">"transactionManager"  ref=class="string">"jotm"  />  
  17.                 <property name=class="string">"driverName"  value=class="string">"com.mysql.jdbc.Driver"  />  
  18.                 <property name=class="string">"url"  value=class="string">"jdbc:MySQL://localhost:3306/test2"  />  
  19.             </bean>  
  20.         </property>  
  21.         <property name=class="string">"user"  value=class="string">"root"  />  
  22.         <property name=class="string">"password"  value=class="string">"admin"  />  
  23.     </bean>  
class="language-java"><bean id="ds1" class="class="hilite1">org
.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
		<property name="dataSource">
			<bean class="class="hilite1">org
.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
				<property name="transactionManager" ref="jotm" />
				<property name="driverName" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:MySQL://localhost:3306/test" />
			</bean>
		</property>
		<property name="user" value="root" />
		<property name="password" value="admin" />
	</bean>
	
	<bean id="ds2" class="class="hilite1">org
.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">
		<property name="dataSource">
			<bean class="class="hilite1">org
.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">
				<property name="transactionManager" ref="jotm" />
				<property name="driverName" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:MySQL://localhost:3306/test2" />
			</bean>
		</property>
		<property name="user" value="root" />
		<property name="password" value="admin" />
	</bean>

这里配置的两个数据源都连接到本地的mysql,实际上可以连接到不同的db server和不同类型的数据库,已经经过测试,这里为了方便,在本地建立了两个不同的数据库(test,test2)做测试。

随后的配置基本上和普通的Spring上下文配置相同了,根据不同的数据源配置两个jdbcTemplate,两个class="tags" href="/tags/DAO.html" title=dao>dao分别引用不同的 jdbcTemplate, 将两个class="tags" href="/tags/DAO.html" title=dao>dao注入到UserService中, 最后将service纳入事务管理,并在事务代理配置中配置回滚规则,意思为如遇异常,则强制回滚内容。配置如下所示

class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. <property name=class="string">"transactionAttributes" >          
  2.     <props>  
  3.         <prop key=class="string">"insert*" >PROPAGATION_REQUIRED,-Exception</prop>              
  4.     </props>  
  5. </property>  
class="language-java"><property name="transactionAttributes">        
	<props>
		<prop key="insert*">PROPAGATION_REQUIRED,-Exception</prop>            
	</props>
</property>


这样,一个使用JOTM
class="hilite4">JTA 事务的简单应用算大致成型了,最后,写一个 JUnit,来测试一下结果
TestXa.java
class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. class="keyword">package  com.xa;  
  2.   
  3. class="keyword">import  class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .context.ApplicationContext;  
  4. class="keyword">import  class="hilite1">org .class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework .test.AbstractDependencyInjectionSpringContextTests;  
  5.   
  6. class="keyword">import  com.xa.service.UserService;  
  7.   
  8. class="keyword">public  class="keyword">class  TestXa class="keyword">extends  AbstractDependencyInjectionSpringContextTests  
  9. {  
  10.     class="keyword">protected  String[] getConfigLocations() {  
  11.         class="keyword">return  class="keyword">new  String[] { class="string">"classpath:ApplicationContext-jotm.xml"  };  
  12.     }  
  13.   
  14.     class="keyword">public  class="keyword">void  testInsertBothDatabase() {  
  15.         ApplicationContext ctx = class="keyword">this .getApplicationContext();  
  16.         UserService ut = (UserService)ctx.getBean(class="string">"userTest" );  
  17.         class="keyword">try  {  
  18.             ut.insertBothDatabase(class="string">"1"class="keyword">null );  
  19.         }  
  20.         class="keyword">catch  (Exception e) {  
  21.             e.printStackTrace();  
  22.         }  
  23.     }  
  24. }  
class="language-java">package com.xa;

import class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.context.ApplicationContext;
import class="hilite1">org
.class="hilite2">class="tags" href="/tags/SPRING.html" title=spring>springframework
.test.AbstractDependencyInjectionSpringContextTests;

import com.xa.service.UserService;

public class TestXa extends AbstractDependencyInjectionSpringContextTests
{
	protected String[] getConfigLocations() {
		return new String[] { "classpath:ApplicationContext-jotm.xml" };
	}

	public void testInsertBothDatabase() {
		ApplicationContext ctx = this.getApplicationContext();
		UserService ut = (UserService)ctx.getBean("userTest");
		try {
	        ut.insertBothDatabase("1", null);
        }
        catch (Exception e) {
        	e.printStackTrace();
        }
	}
}

在test中,调用了UserService的insertBothDatabase方法,有两个参数,userId和UserName,另外在 方法的实现中调用了两个使用不同数据源class="tags" href="/tags/DAO.html" title=dao>dao,分别向两个不同的数据库插入输入,而test2数据库的xa_test表中,name字段是不允许为空的, 因此,在插入test2数据库时会失败.

运行这个test,然后察看数据库结果:),test和test2数据库中都没有插入成功,看serviceImpl中的代码可以知道,逻辑上 class="tags" href="/tags/DAO.html" title=dao>dao1会先于class="tags" href="/tags/DAO.html" title=dao>dao2执行,但是由于
class="hilite4">JTA 事务,在class="tags" href="/tags/DAO.html" title=dao>dao2插入数据出现异常时整个事务被 回滚,由于事务被配置在service层,class="tags" href="/tags/DAO.html" title=dao>dao1和class="tags" href="/tags/DAO.html" title=dao>dao2都被纳入一个事务进行管理,呵呵。修改一下方法的参数,修改为
class="dp-highlighter">
class="bar">
class="tools"> Java 代码
    class="dp-j">
  1. ut.insertBothDatabase(class="string">"1"class="string">"name1" );  
class="language-java">ut.insertBothDatabase("1", "name1");


然后再试试test看数据库结果,如何?


第三节将简单介绍Atomikos在Spring中的配置和使用。
()


http://www.niftyadmin.cn/n/1050074.html

相关文章

虚拟内存及优化方法

http://www.sina.com.cn 2002/01/22 16:53 赛迪网--中国电脑教育报   文/马哲   众所周知&#xff0c;操作系统的任务主要是合理地调配系统的各种资源&#xff0c;为各种程序提供运行环境&#xff0c;它可以被看做是硬件和应用软 件之间的一种媒介。其中对内存的管…

对于Python的感想

选择这门课程的原因第一是对人工智能等方面的知识比较感兴趣&#xff0c;二是认为现在这个时代下学习一些编程知识十分必要。因为自己是一名财会专业的学生&#xff0c;对于这个专业&#xff0c;智能化也是其中的发展方向之一&#xff0c;希望老师在讲课时也可以讲一些编程在经…

hdu 2023 求平均成绩(c语言)

hdu 2023 求平均成绩 点击做题网站链接 题目描述 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Description 假设一个班有n(n<50)个学生&#xff0c;每人考m(m<5)门课&#xff0c;求每个学生的平均成绩和每门课的平均成绩…

Persistence API:持久性单元(Persistence Units)

如果你打算在你的应用中使用JPA&#xff0c;你就需要使用持久性单元(Persistence Units)。持久性单元具有唯一的名称&#xff0c;负责定义应用中的一组实体如何进行管理和持久性。在应用中使用persistence .xml文件来设置持久性单元&#xff0c;可以配置多个持久性单元&#xf…

消息传递

传送门 消息传递 解题思路 一开始怎么觉得那么难&#xff0c;后来稍微一问mjt大佬怎么那么简单&#xff1f; 意思就是你选一个人进行消息传递&#xff0c;然后求最少时间。 所以每个点都有当根节点的机会&#xff0c;遍历根节点。 然后就是儿子节点的问题了&#xff0c;然后就用…

JAVA上加密算法的实现用例(转)

2001 年 7 月 04 日 通常,使用的加密算法 比较简便高效,密钥简短&#xff0c;加解密速度快&#xff0c;破译极其困难。本文介绍了 MD5/SHA1&#xff0c;DSA&#xff0c;DESede/DES&#xff0c;Diffie-Hellman的使用。 第1章基础知识 1.1. 单钥密码体制 单钥密码体…

高性能的MySQL(6)查询慢与重构查询

只有好的库表结构、合理的索引还不够&#xff0c;我们还需要合理的设计查询&#xff0c;齐头并进&#xff0c;一个不少才能充分发挥MySQL的优势。一、查询为什么会慢&#xff1f;每一个查询由一系列的子任务组成&#xff0c;每个子任务都会消耗一定的时间。这个我们在之前的单个…

JS判断客户端是IOS还是ANDROID

//判断app是ios还是androidexport function isIosorAndroid():string{let u navigator.userAgent;let isAndroid u.indexOf(Android) > -1 || u.indexOf(Adr) > -1; //判断是否是 android终端let isiOS !!u.match(/\(i[^;];( U;)? CPU.Mac OS X/); //判断是否是 ios终…