发表于: 2018-03-26 14:41:18
1 345
今天完成的事
直接执行main流程,在服务器上跑通
去找了一个之前main函数里已经写好的工程
执行结果是这样的
将该工程上传到服务器
使用cd命令到工程目录下
使用mvn compile命令编译源代码,当然我这里已经编译执行过了,所以已经有了编译好的文件,不过所依赖的包仍会自动下载。
可以看出也成功执行了
下一个步骤是关于数据库连接池的,想先对数据库连接池做一个学习。
首先我们要知道为什么要使用数据库连接池,以我现在知道的知识,进行数据库的连接是挺消耗性能的,不停的连接和关闭与数据库的连接,是更加需要避免的事。所以就有人想到并搞了这么一个,用于存放数据库连接并管理它们的东西。事先就建立好一些与数据库的连接,将它们存放在数据库连接池中,等到有对数据库操作的请求时,就从池子中取出来返回给他们。当操作结束时,就将这个连接继续存储在池子中。这样,建立连接这样一个步骤就几乎在程序运行过程中被避免了。(使用几乎这个词是因为还是有需要建立连接的情况)
在网上查找资料时看到一段数据库连接池的实现源码,仔细阅读后感觉对数据库连接池的理解更深了一步。结合原博主的解释加上自己的理解,试着给源码注释。
1. public PooledDataSource() {
2. dataSource = new UnpooledDataSource();//使用数据库连接池的数据源其实就是不使用数据库连接池数据源的包装类。包装类就是对原有的类实现功能加强。
3. }
1. protected final List<PooledConnection> idleConnections = new ArrayList<PooledConnection>();
2. protected final List<PooledConnection> activeConnections = new ArrayList<PooledConnection>();
3. //两个存放数据库连接的数据,很明显,一个是存放空闲连接的,另外一个是存放已经使用的连接的。
1. @Override
2. public Connection getConnection() throws SQLException {
3. return popConnection(dataSource.getUsername(), dataSource.getPassword()).getProxyConnection();//根据用户名和密码获得数据源.
4. }
5.
6. private PooledConnection popConnection(String username, String password) throws SQLException {
7. boolean countedWait = false; //是否等待状态
8. PooledConnection conn = ; //连接对象
9. long t = System.currentTimeMillis();
10. int localBadConnectionCount = 0;
11.
12. while (conn == ) {
13. synchronized (state) {
14. if (!state.idleConnections.isEmpty()) {
15. // Pool has available connection
16. conn = state.idleConnections.remove(0); //若有空闲的连接,则取出第一个
17. if (log.isDebugEnabled()) {
18. log.debug("Checked out connection " + conn.getRealHashCode() + " from pool."); //log就是日志,看到这里对日志的作用有了更深的体会,之前以为只是存放程序运行后所返回的结果。而现在这些背后我们所看不到的操作所带来的变化,就是通过日志反馈给我们的。
19. }
20. } else {
21. // Pool does not have available connection
22. if (state.activeConnections.size() < poolMaximumActiveConnections) { //这里要说一下数据库连接池一般有一个最大连接数量,一般情况下所维持的连接是小于这个数量的,若请求连接的数量大于维持的数量时,通过判断可以再创建连接。
23. // Can create new connection
24. conn = new PooledConnection(dataSource.getConnection(), this);
25. if (log.isDebugEnabled()) {
26. log.debug("Created connection " + conn.getRealHashCode() + ".");
27. }
28. } else {
29. // Cannot create new connection
30. PooledConnection oldestActiveConnection = state.activeConnections.get(0);
31. long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();
32. if (longestCheckoutTime > poolMaximumCheckoutTime) {
33. // Can claim overdue connection
34. state.claimedOverdueConnectionCount++;
35. state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;
36. state.accumulatedCheckoutTime += longestCheckoutTime;
37. state.activeConnections.remove(oldestActiveConnection);
38. //若不能再创建连接,则会去找连接时间最长的连接,将它踢出活跃状态
39. if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {
40. try {
41. oldestActiveConnection.getRealConnection().rollback();
42. } catch (SQLException e) {
43. /*
44. Just log a message for debug and continue to execute the following
45. statement like nothing happend.
46. Wrap the bad connection with a new PooledConnection, this will help
47. to not intterupt current executing thread and give current thread a
48. chance to join the next competion for another valid/good database
49. connection. At the end of this loop, bad {@link @conn} will be set as null.
50. */
51. log.debug("Bad connection. Could not roll back");
52. //我感觉这里的意思是可能这个连接坏了,或者还有在执行的业务?所以不能踢掉.
53. }
54. }
55. conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);
56. conn.setCreatedTimestamp(oldestActiveConnection.getCreatedTimestamp());
57. conn.setLastUsedTimestamp(oldestActiveConnection.getLastUsedTimestamp());
58. oldestActiveConnection.invalidate();
59. if (log.isDebugEnabled()) {
60. log.debug("Claimed overdue connection " + conn.getRealHashCode() + ".");
61. //这里应该是用新的连接替代超时连接
62. }
63. } else {
64. // Must wait
65. try {
66. if (!countedWait) {
67. state.hadToWaitCount++;
68. countedWait = true;
69. }
70. if (log.isDebugEnabled()) {
71. log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection.");
72. }
73. long wt = System.currentTimeMillis();
74. state.wait(poolTimeToWait);
75. state.accumulatedWaitTime += System.currentTimeMillis() - wt;
76. } catch (InterruptedException e) {
77. break;
78. }
79. }
80. }
81. }
82. if (conn != ) {
83. // ping to server and check the connection is valid or not
84. if (conn.isValid()) {
85. if (!conn.getRealConnection().getAutoCommit()) {
86. conn.getRealConnection().rollback();
87. }
88. conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password));
89. conn.setCheckoutTimestamp(System.currentTimeMillis());
90. conn.setLastUsedTimestamp(System.currentTimeMillis());
91. state.activeConnections.add(conn);
92. state.requestCount++;
93. state.accumulatedRequestTime += System.currentTimeMillis() - t;
94. } else {
95. if (log.isDebugEnabled()) {
96. log.debug("A bad connection (" + conn.getRealHashCode() + ") was returned from the pool, getting another connection.");
97. }
98. state.badConnectionCount++;
99. localBadConnectionCount++;
100. conn = ;
101. if (localBadConnectionCount > (poolMaximumIdleConnections + poolMaximumLocalBadConnectionTolerance)) {
102. if (log.isDebugEnabled()) {
103. log.debug("PooledDataSource: Could not get a good connection to the database.");
104. }
105. throw new SQLException("PooledDataSource: Could not get a good connection to the database.");
106. }
107. }
108. }
109. }
110.
111. }
112.
113. if (conn == ) {
114. if (log.isDebugEnabled()) {
115. log.debug("PooledDataSource: Unknown severe error condition. The connection pool returned a null connection.");
116. }
117. throw new SQLException("PooledDataSource: Unknown severe error condition. The connection pool returned a null connection.");
118. }
119.
120. return conn;
121. }
还没注释完,先去上课了,晚上去听个关于人工智能的讲座。了解一下当下的热门,应该也挺好。
明天计划的事情:
继续对数据库连接池的学习。
遇到的困难:
其实注释到一半发现好像并没有完全理解,明天继续努力!
收获:
服务器跑通main程序,数据库连接池的学习。
评论