package com.yiqiniu.easytrans.datasource.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Resource; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceUtils; import com.yiqiniu.easytrans.datasource.DataSourceSelector; import com.yiqiniu.easytrans.datasource.TransStatusLogger; public class DefaultTransStatusLoggerImpl implements TransStatusLogger { @Resource DataSourceSelector selctor; public void setSelctor(DataSourceSelector selctor) { this.selctor = selctor; } private ConcurrentHashMap<DataSource, JdbcTemplate> mapJdbcTemplate = new ConcurrentHashMap<DataSource, JdbcTemplate>(); @Override public Boolean checkTransactionStatus(String appId, String busCode, String trxId) { DataSource dataSource = selctor.selectDataSource(appId, busCode, trxId); JdbcTemplate jdbcTemplate = getJdbcTemplate(dataSource); //select * for update Integer count = jdbcTemplate.queryForObject("select count(1) from executed_trans where app_id = ? and bus_code = ? and trx_id = ? for update;", new Object[]{appId,busCode,trxId}, Integer.class); if(count == null){ return null; }else if(count >= 1){ return true; }else{ return false; } } private JdbcTemplate getJdbcTemplate(DataSource dataSource) { JdbcTemplate jdbcTemplate = mapJdbcTemplate.get(dataSource); if(jdbcTemplate == null){ jdbcTemplate = new JdbcTemplate(dataSource); mapJdbcTemplate.put(dataSource, jdbcTemplate); } return jdbcTemplate; } @Override public void writeExecuteFlag(String appId, String busCode, String trxId) { Connection connection = DataSourceUtils.getConnection(selctor.selectDataSource(appId, busCode, trxId)); try { PreparedStatement prepareStatement = connection.prepareStatement("INSERT INTO `executed_trans` (`app_id`, `bus_code`, `trx_id`) VALUES ( ?, ?, ?);"); prepareStatement.setString(1, appId); prepareStatement.setString(2, busCode); prepareStatement.setString(3, trxId); int executeUpdate = prepareStatement.executeUpdate(); if(executeUpdate != 1){ throw new RuntimeException(String.format("insert count(%s) Error!%s %s %s", executeUpdate,appId,busCode,trxId)); } } catch (SQLException e) { throw new RuntimeException("insert Sql failed,check whether the same transaction has been executed?",e); } } }