如何避免在Java中意外关闭SQL连接?

时间:2022-12-16 14:08:14

Currently what i am doing for transaction management is:

目前我正在做的事务管理是:

Connection connection = getConnection();
connection.setAutoCommit(false);
updateTableX ( connection, ... );
updateTableY ( connection, ... );
connection.commit();
closeConnection();

I would like to know, if it is possible to avoid closing the connection in my 'updateTableX' method. Because if someone accidentally closes the connection then my updateTableY will not be having the connection and it will throw the exception.

我想知道,如果可以避免在我的'updateTableX'方法中关闭连接。因为如果有人不小心关闭了连接,那么我的updateTableY将没有连接,它将抛出异常。

4 个解决方案

#1


Just discipline. In general, methods shouldn't try to take responsibility for closing things passed into them as parameters - with the exception of situations where you create a new object to wrap an existing one.

只是纪律。通常,方法不应该尝试将作为参数传递给它们的事物关闭 - 除了创建新对象以包装现有对象的情况。

The way to avoid closing the connection in updateTableX is just to make sure you don't put a call to close() into the code. This is no different than any other bug really. How do you stop updateTableX from arbitrarily updating a different table, or throwing an exception, or doing anything else it's not meant to? Code reviews, unit tests, integration tests, manual testing etc...

避免在updateTableX中关闭连接的方法只是为了确保不将close()调用到代码中。这与其他任何bug都没有什么不同。你如何阻止updateTableX随意更新一个不同的表,抛出一个异常,或做任何其他事情并不意味着?代码审查,单元测试,集成测试,手动测试等......

I mean you could write a Connection implementation which wraps another connection and proxies all the methods through except close() but it sounds like a waste of time - if you don't trust the developers involved not to close the connection, do you trust them to get the rest of the code right?

我的意思是你可以编写一个Connection实现来包装另一个连接并代理除close()之外的所有方法,但这听起来像是浪费时间 - 如果你不相信开发人员不关闭连接,你相信它们吗?让其余的代码正确吗?

#2


Like Jon said, if you really want to forbit to call close() you could write a decorator implementation that forwards to your "real" Connection object. I don't post a code example because the Connection interface is too big. With modern IDEs however it is no problem to generate the code.

就像Jon说的那样,如果你真的想要调用close(),你可以编写一个装饰器实现,转发给你的“真正的”Connection对象。我没有发布代码示例,因为Connection接口太大了。使用现代IDE,生成代码没有问题。

Recipe (presuming you're using Eclipse):

食谱(假设你正在使用Eclipse):

  1. Create a class that implements Connection, but do not implement the methods
  2. 创建一个实现Connection的类,但不实现这些方法

  3. Create a field private Connection delegate;
  4. 创建一个字段私有Connection委托;

  5. Select the field name -> Source (Menu) -> "Generate Constructor using fields" -> make sure the field is selected and press ok
  6. 选择字段名称 - >源(菜单) - >“使用字段生成构造函数” - >确保选中该字段并按确定

  7. Select the field name -> Source (Menu) -> "Generate Delegate Methods..." -> check every method on you field
  8. 选择字段名称 - >源(菜单) - >“生成委托方法...” - >检查您字段上的每个方法

  9. Change the implementation of the close() method to throw an UnsupportedOperationException
  10. 更改close()方法的实现以抛出UnsupportedOperationException

However like Jon said, I would really think about doing something like that. And maybe you just use a Object-Relational-Mapper (e.g. Hiberate) to encapsulate all of your Database access logic. An additional very helpful framework in this area is Spring, especially if you do not want to care about Connection and DataSource handling.

不过像Jon说的那样,我真的会考虑做那样的事情。也许您只需使用Object-Relational-Mapper(例如Hiberate)来封装所有数据库访问逻辑。 Spring中有一个非常有用的框架,特别是如果你不想关心Connection和DataSource处理。

#3


(I am unfamiliar with Java specifically)

(我特别不熟悉Java)

Assuming you have some sort of database managing object, you could have it make sure it is connected before it attempts any operations.

假设您有某种数据库管理对象,您可以确保它在尝试任何操作之前已连接。

You could try to restrict access to closing the connection but how would you decide if it should be closed, or if it's "accidental" (however you define that)?

您可以尝试限制关闭连接的访问​​权限,但是您将如何决定是否应该关闭它,或者它是否“意外”(但是您定义了它)?

#4


I don't think what you are asking is possible.

我不认为你问的是可能的。

You can technically make a copy of your connection object, but then what happens if the client programmer doesn't close the connection?

您可以在技术上制作连接对象的副本,但如果客户端程序员没有关闭连接会发生什么?

#1


Just discipline. In general, methods shouldn't try to take responsibility for closing things passed into them as parameters - with the exception of situations where you create a new object to wrap an existing one.

只是纪律。通常,方法不应该尝试将作为参数传递给它们的事物关闭 - 除了创建新对象以包装现有对象的情况。

The way to avoid closing the connection in updateTableX is just to make sure you don't put a call to close() into the code. This is no different than any other bug really. How do you stop updateTableX from arbitrarily updating a different table, or throwing an exception, or doing anything else it's not meant to? Code reviews, unit tests, integration tests, manual testing etc...

避免在updateTableX中关闭连接的方法只是为了确保不将close()调用到代码中。这与其他任何bug都没有什么不同。你如何阻止updateTableX随意更新一个不同的表,抛出一个异常,或做任何其他事情并不意味着?代码审查,单元测试,集成测试,手动测试等......

I mean you could write a Connection implementation which wraps another connection and proxies all the methods through except close() but it sounds like a waste of time - if you don't trust the developers involved not to close the connection, do you trust them to get the rest of the code right?

我的意思是你可以编写一个Connection实现来包装另一个连接并代理除close()之外的所有方法,但这听起来像是浪费时间 - 如果你不相信开发人员不关闭连接,你相信它们吗?让其余的代码正确吗?

#2


Like Jon said, if you really want to forbit to call close() you could write a decorator implementation that forwards to your "real" Connection object. I don't post a code example because the Connection interface is too big. With modern IDEs however it is no problem to generate the code.

就像Jon说的那样,如果你真的想要调用close(),你可以编写一个装饰器实现,转发给你的“真正的”Connection对象。我没有发布代码示例,因为Connection接口太大了。使用现代IDE,生成代码没有问题。

Recipe (presuming you're using Eclipse):

食谱(假设你正在使用Eclipse):

  1. Create a class that implements Connection, but do not implement the methods
  2. 创建一个实现Connection的类,但不实现这些方法

  3. Create a field private Connection delegate;
  4. 创建一个字段私有Connection委托;

  5. Select the field name -> Source (Menu) -> "Generate Constructor using fields" -> make sure the field is selected and press ok
  6. 选择字段名称 - >源(菜单) - >“使用字段生成构造函数” - >确保选中该字段并按确定

  7. Select the field name -> Source (Menu) -> "Generate Delegate Methods..." -> check every method on you field
  8. 选择字段名称 - >源(菜单) - >“生成委托方法...” - >检查您字段上的每个方法

  9. Change the implementation of the close() method to throw an UnsupportedOperationException
  10. 更改close()方法的实现以抛出UnsupportedOperationException

However like Jon said, I would really think about doing something like that. And maybe you just use a Object-Relational-Mapper (e.g. Hiberate) to encapsulate all of your Database access logic. An additional very helpful framework in this area is Spring, especially if you do not want to care about Connection and DataSource handling.

不过像Jon说的那样,我真的会考虑做那样的事情。也许您只需使用Object-Relational-Mapper(例如Hiberate)来封装所有数据库访问逻辑。 Spring中有一个非常有用的框架,特别是如果你不想关心Connection和DataSource处理。

#3


(I am unfamiliar with Java specifically)

(我特别不熟悉Java)

Assuming you have some sort of database managing object, you could have it make sure it is connected before it attempts any operations.

假设您有某种数据库管理对象,您可以确保它在尝试任何操作之前已连接。

You could try to restrict access to closing the connection but how would you decide if it should be closed, or if it's "accidental" (however you define that)?

您可以尝试限制关闭连接的访问​​权限,但是您将如何决定是否应该关闭它,或者它是否“意外”(但是您定义了它)?

#4


I don't think what you are asking is possible.

我不认为你问的是可能的。

You can technically make a copy of your connection object, but then what happens if the client programmer doesn't close the connection?

您可以在技术上制作连接对象的副本,但如果客户端程序员没有关闭连接会发生什么?