zoukankan      html  css  js  c++  java
  • Spring事务管理 | 使用ProxyFactoryBean/Transaction Interceptor

    控制层:

    import java.math.BigDecimal;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.prospring.ticket.service.PaymentService;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    @RequestMapping("/payment")
    public class PaymentController {
        @Autowired
        private PaymentService paymentService;
    
        @RequestMapping(method = RequestMethod.GET, value = "/transfer")
        @ResponseBody
        public String tranfer(
                @RequestParam(value = "sourceAccount", required = 
    true
    ) String sourceAccount,
                @RequestParam(value = "targetAccount", required = 
    true
    ) String targetAccount,
                @RequestParam(value = "money", required = 
    true
    ) BigDecimal money)
                throws Exception {
            paymentService.transfer(sourceAccount, targetAccount, money);
            return "{rs_code:0}";
        }
    }

    业务逻辑层:

    import java.math.BigDecimal;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.prospring.ticket.aop.interceptor.DebugInterceptor;
    import org.springframework.prospring.ticket.dao.PaymentDao;
    import org.springframework.prospring.ticket.domain.Account;
    
    public class PaymentServiceImpl implements PaymentService {
        private PaymentDao paymentDao;
        
        @Override
        public void transfer(String sourceAccountNumber, String targetAccountNumber,
                BigDecimal money) {
            Account sourceAccount = paymentDao.getAccount(sourceAccountNumber);
            Account targetAccount = paymentDao.getAccount(targetAccountNumber);
            paymentDao.updateAccount(sourceAccountNumber, sourceAccount.getBalance().subtract(money));
            paymentDao.updateAccount(targetAccountNumber, targetAccount.getBalance().add(money));
        }
    
        /**
         * @param paymentDao the paymentDao to set
         */
        public void setPaymentDao(PaymentDao paymentDao) {
            this.paymentDao = paymentDao;
        }
    
    }

    Dao层:

    import java.math.BigDecimal;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import org.springframework.dao.DataAccessException;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.PreparedStatementCallback;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    import org.springframework.prospring.ticket.domain.Account;
    
    public class PaymentDao {
        private JdbcTemplate jdbcTemplate;
        
        public Account getAccount(String account) {
            return (Account) this.jdbcTemplate.query("select id, name, balance from account where id = ?", new Object[]{account},new RowMapper(){
                @Override
                public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                    Account account = new Account();
                    account.setId(rs.getString("id"));
                    account.setName(rs.getString("name"));
                    account.setBalance(rs.getBigDecimal("balance"));
                    return account;
                }
                
            }).get(0);
        }
        
        public void updateAccount(final String account, final BigDecimal money) {
            this.jdbcTemplate.execute("update account set balance = ? where id = ?", new PreparedStatementCallback() {
                @Override
                public Object doInPreparedStatement(PreparedStatement ps)
                        throws SQLException, DataAccessException {
                    ps.setBigDecimal(1, money);
                    ps.setString(2, account);
                    ps.executeUpdate();
                    return null;
                }
            });
        }
    
        /**
         * @param jdbcTemplate the jdbcTemplate to set
         */
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
        
    }

    配置文件1:web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      id="WebApp_ID" version="3.0">
      <display-name>bookstore</display-name>
    
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
         classpath*:spring/*.xml
       </param-value>
      </context-param>
      
      <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:conf/log4j.properties</param-value>
      </context-param>
      
      <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>bookstore.root</param-value>
      </context-param>
    
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
      <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
      </listener>
      
      <servlet>
        <servlet-name>bookstore</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      
      <servlet-mapping>
        <servlet-name>bookstore</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
      
      <!-- session -->
      <session-config>
        <session-timeout>60</session-timeout>
      </session-config>
    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    
      <error-page>
        <error-code>403</error-code>
        <location>/error.html</location>
      </error-page>
    
    </web-app>

    配置文件2:applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
        <!--从配置文件读取配置信息 -->
        <bean id="propertyConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
            <property name="ignoreResourceNotFound" value="true" />
            <property name="locations">
                <list>
                    <value>classpath*:conf/jdbc.properties</value>
                </list>
            </property>
        </bean>
    
        <!-- The DBCP DataSource -->
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
            <property name="driverClassName">
                <value>${jdbc.driverClassName}</value>
            </property>
            <property name="url">
                <value>${jdbc.url}</value>
            </property>
            <property name="username">
                <value>${jdbc.username}</value>
            </property>
            <property name="password">
                <value>${jdbc.password}</value>
            </property>
        </bean>
    
        <!-- 配置JdbcTemplate -->
        <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
            <property name="dataSource" ref="dataSource"></property>
        </bean>
    
        <!-- The DAO class -->
        <bean id="paymentDao" class="org.springframework.prospring.ticket.dao.PaymentDao">
            <property name="jdbcTemplate">
                <ref local="jdbcTemplate" />
            </property>
        </bean>
    
        <!-- The transactionmanager to use for regular non JTA datasource -->
        <bean id="transactionManager"
            class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource">
                <ref local="dataSource" />
            </property>
        </bean>
    
        <!-- Business Object -->
        <bean id="paymentServiceTarget"
            class="org.springframework.prospring.ticket.service.PaymentServiceImpl">
            <property name="paymentDao">
                <ref local="paymentDao" />
            </property>
        </bean>
    
        <!-- TransactionInterceptor -->
        <bean id="transactionInterceptor"
            class="org.springframework.transaction.interceptor.TransactionInterceptor">
            <property name="transactionManager">
                <ref bean="transactionManager" />
            </property>
            <property name="transactionAttributeSource">
                <value>
                    org.springframework.prospring.ticket.service.PaymentService.transfer=PROPAGATION_REQUIRED,ISOLATION_SERIALIZABLE,timeout_30,-Exception
                </value>
            </property>
        </bean>
    
        <!-- Transactional proxy for the primary business object -->
        <bean id="paymentService" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="target">
                <ref local="paymentServiceTarget" />
            </property>
            <property name="proxyInterfaces">
                <value>org.springframework.prospring.ticket.service.PaymentService
                </value>
            </property>
            <property name="interceptorNames">
              <list>
                <value>transactionInterceptor</value>
              </list>
            </property>
        </bean>
     
    </beans>

    配置文件3:jdbc.properties

    # Mysql驱动
    jdbc.driverClassName=com.mysql.jdbc.Driver
    # Mysql主机、端口、数据库名
    jdbc.url=jdbc:mysql://localhost:6688/spring?useUnicode=true&characterEncoding=UTF-8
    # Mysql用户名
    jdbc.username=admin
    # Mysql密码
    jdbc.password=admin

    配置文件4:log4j.properties

    log4j.rootLogger=INFO,CONSOLE,ROLLING_FILE
    #log4j.rootLogger=ERROR,CONSOLE,ROLLING_FILE
    log4j.debug=true
    ###################
    # Console Appender
    ###################
    
    log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
    log4j.appender.Threshold=INFO
    log4j.appender.CONSOLE.Target=System.out
    log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n
    
    ########################
    # Rolling File
    ########################
    log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
    log4j.appender.ROLLING_FILE.Threshold=INFO
    log4j.appender.ROLLING_FILE.File=${bookstore.root}/logs/bookstore.log
    log4j.appender.ROLLING_FILE.Append=true
    log4j.appender.ROLLING_FILE.MaxFileSize=5000KB
    log4j.appender.ROLLING_FILE.MaxBackupIndex=100
    log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
    log4j.appender.ROLLING_FILE.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
  • 相关阅读:
    蓝桥杯Java真题解析
    第十届蓝桥杯JavaB组总结
    Java框架相关
    认识JDBC
    Lua中 MinXmlHttpRequest如何发送post方式数据
    ios 的EditBox点击空白处不隐藏的解决方案
    AssetsManager 在ios更新失败解决方案
    Cocos Studio编辑器运行日志路径
    华为 进入和退出Fastboot、eRecovery和Recovery升级模式
    cocos lua 加密方案
  • 原文地址:https://www.cnblogs.com/xder/p/5142263.html
Copyright © 2011-2022 走看看