Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Nhóm kết nối jdbc của Tomcat - giao dịch bị bỏ qua khôi phục

Theo http://docs .oracle.com / javase / 7 / docs / api / java / sql / Connection.html # close () :

Thử nghiệm này, sử dụng Mysql thay vì Oracle xác nhận sự thật này:

import static org.junit.Assert.assertEquals;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;


public class DBTest {

    public Connection openConnection() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");
        c.setAutoCommit(false);
        return c;
    }

    @Test
    public void testSO25886466() throws SQLException, ClassNotFoundException {

        {
            Connection c = openConnection();
            PreparedStatement delete = c.prepareStatement("delete from temp");
            delete.executeUpdate();
            c.commit();
            c.close();
        }

        {
            Connection c = openConnection();
            PreparedStatement insert = c.prepareStatement("insert into temp values ('a', 'b')");
            insert.execute();
            //c.commit(); as the op says, DONT commit!!
            c.close(); //WITHOUT having closed the statement or committing the transaction!!
        }

        {
            Connection c = openConnection();
            PreparedStatement select = c.prepareStatement("select count(*) from temp");
            select.execute();
            ResultSet rs = select.getResultSet();
            while(rs.next()){
                assertEquals(0/*i'd expect zero here!*/, rs.getInt(1));
            }
            rs.close();
            select.close();
            c.close();
        }
    }
}

Theo http://tomcat.apache.org/tomcat-7.0 -doc / jdbc-pool.html :

Tôi khuyên bạn không nên đặt removeAbandoned để Oracle đóng kết nối sau một khoảng thời gian chờ ở phía máy chủ, thay vì Tomcat đóng nó. Oracle có thể sẽ không thực hiện giao dịch trong trường hợp đó, nhưng bạn sẽ cần phải kiểm tra điều này.

Ngoài ra, bạn có thể tăng removeAbandonedTimeout để chương trình của bạn có thể kết thúc và không có kết nối nào bị bỏ rơi?

Một vấn đề khác mà bạn gặp phải là ứng dụng của bạn đã bị ràng buộc với Oracle vì bạn đang dựa vào việc triển khai trình điều khiển mà thông số kỹ thuật có một lỗ hổng trong đó. Nếu bạn có thể, hãy lập trình dựa trên các thông số kỹ thuật để bạn có thể tự do di chuyển ứng dụng của mình sang một cơ sở dữ liệu khác, mặc dù tôi biết điều đó là khó trong thực tế.

Một giải pháp hoàn toàn khác sẽ là sử dụng một nhóm kết nối mã nguồn mở và mở rộng nó với một bộ đánh chặn AOP có thể chặn các cuộc gọi đến close và xác định xem giao dịch đã được cam kết chưa và nếu chưa, hãy gọi rollback trên kết nối. Đó là một giải pháp khá phức tạp mặc dù ... :-)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle, cách mở con trỏ và chọn một cột trong số nhiều cột vào một biến

  2. Lấy dữ liệu từ bảng bằng PL / SQL

  3. bảng hoặc chế độ xem không tồn tại

  4. Ngoại lệ triển khai weblogic:PaddingException:Không thể thực hiện việc bỏ đệm:byte đệm không hợp lệ

  5. làm thế nào để chọn các giá trị xuất hiện thường xuyên nhất?