`

Spring + jdbc +connection pool + transaction

 
阅读更多
1. 添加lib
<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>3.2.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>3.2.6.RELEASE</version>
		</dependency>


2. 修改spring配置
<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.2.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

	<!-- scan all beans and inject dependence -->
	<context:component-scan base-package="com.myproject"/>
	<!-- add aop support -->
	<aop:aspectj-autoproxy/>
	
	<!-- read from database.properties -->
	<context:property-placeholder location="classpath:database.properties"/>
	<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${driverClassName}"></property>
		<property name="url" value="${url}"/>
	    <property name="username" value="root"/>
	    <property name="password" value="admin"/>
	     <!-- 连接池启动时的初始值 -->
		 <property name="initialSize" value="${initialSize}"/>
		 <!-- 连接池的最大值 -->
		 <property name="maxActive" value="${maxActive}"/>
		 <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
		 <property name="maxIdle" value="${maxIdle}"/>
		 <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
		 <property name="minIdle" value="${minIdle}"/>
	</bean>
	
	<!-- add Transaction support -->
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="datasource"/>
	</bean>
	<!-- add Transaction support in annotation format -->
	<tx:annotation-driven transaction-manager="txManager"/>
</beans>



3.添加AccountDao
import java.sql.Types;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class AccountDaoBean implements AccountDao{
	
	private JdbcTemplate jdbcTemplate;
	
	@Resource
	public void setDataSource(DataSource datasource){
		this.jdbcTemplate=new JdbcTemplate(datasource);
	}
	
	@Override
	public int insertAccount(Account account) {
		String sql="insert into account(username, password) values(?, ?)";
		return this.jdbcTemplate.update(sql, new Object[]{account.getUsername(), account.getPassword()}, 
				new int[]{java.sql.Types.VARCHAR, java.sql.Types.VARCHAR});
	}

	@Override
	public Account queryAccountById(int id) {
		String sql="select * from account where id =?";
		return this.jdbcTemplate.queryForObject(sql, new Object[]{id}, 
				new int[]{java.sql.Types.INTEGER}, new AccountMapper());
	}

	@Override
	public List<Account> queryAccount(Account account) {
		String sql="select * from account where 1=1 ";
		if(account.getUsername()!=null)
			sql=sql+"and username=? ";
		if(account.getPassword()!=null)
			sql=sql+"and password=? ";
		return this.jdbcTemplate.query(sql, new Object[]{account.getUsername(), account.getPassword()}, 
				new int[]{java.sql.Types.VARCHAR, java.sql.Types.VARCHAR}, new AccountMapper());
	}

	@Override
	public int updateAccount(Account account) {
		String sql="update account set username=?, password=? where id=?";
		return this.jdbcTemplate.update(sql, new Object[]{account.getUsername(), account.getPassword(), account.getId()}, 
				new int[]{Types.VARCHAR, Types.VARCHAR, Types.INTEGER});
	}

	@Override
	public int deleteAccount(int id) {
		String sql="delete from account where id=?";
		return this.jdbcTemplate.update(sql, new Object[]{id}, 
				new int[]{Types.INTEGER});
	}
}



4.添加RowMapper
import org.springframework.jdbc.core.RowMapper;
public class AccountMapper implements RowMapper<Account>{

	@Override
	public Account mapRow(ResultSet rs, int index) throws SQLException {
		Account account = new Account();
		account.setId(rs.getInt("id"));
		account.setUsername("username");
		account.setPassword("password");
		return account;
	}
}



添加Service
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class AccountService {
	
	@Resource
	private AccountDao accountDao;
	
	//don't need to add transaction in query method 
	@Transactional(propagation=Propagation.NOT_SUPPORTED)
	public Account Login(String username, String password){
		System.out.println(username + " want  to login.");
		Account account = new Account();
		account.setUsername(username);
		account.setPassword(password);
		List<Account> list=  accountDao.queryAccount(account);
		if(list.size()==1)
			return list.get(0);
		else 
			return null;
	}
	
	//in method which already has "throws", we must add rollbackFor if want to rollback for this exception,
	//otherwise the method will not be rollback
	@Transactional(rollbackFor=Exception.class)
	public void reqister(Account account) {
		accountDao.insertAccount(account);
		throw new RuntimeException("==no register");
	}
}



测试
@Test
	public void test(){
		try {
			ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
			AccountService accountService =(AccountService)ac.getBean("accountService");
			
			Account account = new Account();
			account.setUsername("tom");
			account.setPassword("116");
			accountService.reqister(account);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


注意:
  • 1. 用@Transactional修饰的class默认情况下会对每个method加上独立的事务,当一个method被另一个method调用时,事务会合并。
  • 2. 默认情况下方法内抛出runtime异常,会rollback。 但如果方法定义中有throws *Exception, 不会对抛出的*Exception回滚; 如果需要回滚*Exception,需要对方法加上注释@Transactional(rollbackFor=*Exception.class)。
  • 3. 原理同#2, 我们也可以使用@Transactional(noRollbackFor=*Exception.class)指定不回滚某种异常。
  • 4. 在#1中指出@Transactional修饰的class默认情况下会对每个method加上独立的事务,对于查询方法我们可以使用注释@Transactional(propagation=Propagation.NOT_SUPPORTED)申明该方法不需要事务管理。  propagation 还有其他属性(见附件):
  • 大小: 27.9 KB
分享到:
评论

相关推荐

    spring+druid+AtomikosDataSource实现多数据源切换及分布式事务控制

    Spring提供了对多种数据源的支持,包括JDBC DataSources和Transaction Managers。通过Spring的配置,我们可以轻松地管理多个数据源,并根据业务逻辑进行动态切换。这通常涉及到使用`@Qualifier`注解来指定特定的...

    spring整合jdbc hbm struts 的各种配置

    &lt;property name="hibernate.connection.url"&gt;jdbc:oracle:thin:@127.0.0.1:1521:orcl &lt;property name="hibernate.dialect"&gt;org.hibernate.dialect.Oracle9Dialect &lt;!-- ...其他配置... --&gt; ``` 2. 在 Spring ...

    phase3-spring-jdbc-template-03-07-2021

    6. **Connection Pool Integration**: Spring JDBC Template可以与各种连接池集成,如HikariCP, C3P0, Apache DBCP等,以提高数据库连接的复用性和性能。 描述中没有提供具体的信息,所以我们将聚焦于Spring JDBC ...

    dbcp 连接池不合理的锁导致连接耗尽解决方案

    DBCP(Database Connection Pool)是Apache的一个开源项目,提供了一个基于Java的数据源连接池实现。在上述问题中,应用程序遇到了由于连接池不合理的锁机制导致的连接耗尽问题,表现为无法从连接池获取新的数据库...

    spring框架jar包,已经分类

    5. **Spring JDBC**和**Spring ORM**:提供对JDBC的抽象层,简化数据库操作,并且支持各种ORM框架如Hibernate和MyBatis的集成。 6. **Spring Transaction Management**:提供统一的事务管理接口,支持编程式和声明式...

    spring核心jar

    DBCP是Spring支持的一种连接池实现,但请注意,较新的Spring项目可能使用更现代的连接池,如HikariCP或Tomcat JDBC Pool。 4. **spring-dao-2[1].0-m1.jar**:这个文件包含了Spring的DAO(Data Access Object)模块...

    揭秘JDBC超时机制完整版

    Transaction Timeout通常在框架(如Spring、EJB)或应用程序级别设定,用于限制一系列SQL语句(即一个事务)的总执行时间。它不是单个statement的超时,而是所有statement加上其他非SQL执行时间(如垃圾回收)的总和...

    H2Database中文教程

    &lt;jdbc-connection-pool name="h2Pool" res-type="javax.sql.DataSource" driver-classname="org.h2.Driver"&gt; &lt;property name="URL" value="jdbc:h2:~/test"&gt; &lt;property name="User" value="sa"&gt;&lt;/property&gt; ...

    spring声明式事务解析

    Spring并不直接管理事务,而是利用JTA(Java Transaction API)或者特定持久层技术(如JDBC、JPA、Hibernate等)提供的事务实现。Spring通过AOP(面向切面编程)来实现事务管理,创建代理对象来增强目标方法,将事务...

    J2EE应用中与Oracle数据库的连接.rar_oracle

    2. JDBC Connection Pool(连接池): - 提供了一种管理数据库连接的方式,如C3P0、HikariCP等。连接池可以提高应用性能,减少数据库资源的创建和销毁开销。优点在于资源复用,缺点是需要配置和管理。 二、JNDI...

    java 开发

    在Java开发中,数据库连接池(Connection Pool)是一个常见的优化手段,它可以提高数据库操作的效率和系统的响应速度。Apache的Commons DBCP、C3P0以及HikariCP都是常用的Java数据库连接池实现。它们能够有效地管理...

    MyEclipse报错说明

    3. **Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update** Hibernate在执行数据库批处理更新时出现SQL语法错误,可能是由于数据库表不存在或结构不符...

    ConnMethods.zip_Java编程_Java_

    4. **Connection Pool(连接池)** 连接池技术如C3P0、HikariCP、Apache DBCP等,能提高性能并有效管理数据库连接。它们预先创建一定数量的连接,当需要时分配,用完后归还,避免了频繁创建和关闭连接的开销。 5. ...

    dorado7链接数据库文件

    在这个配置文件中,`&lt;bean id="dataSource"&gt;`定义了一个名为`dataSource`的数据源Bean,该Bean实现了Apache Commons DBCP(Database Connection Pool)的数据源接口。 - **URL**: `jdbc:oracle:thin:@127.0.0.1:...

    hibernate3.5.6开发包

    10. **性能优化**:包括延迟加载(lazy loading)、批处理(batch processing)、预加载(preloading)、连接池(connection pool)等技术,都是Hibernate性能优化的重要手段。 **标签:“Hibernate”** 在实际...

    agroal:自然数据库连接池

    2. **自动配置**:Agroal支持自动配置,与Spring Boot等现代开发框架无缝集成,简化了配置过程,开发者只需提供必要的数据库连接信息即可。 3. **事务支持**:支持JTA(Java Transaction API)事务管理,使得在...

Global site tag (gtag.js) - Google Analytics