漠北空城

听海观潮


  • 首页

  • 关于

  • 标签

  • 归档

  • 搜索

SpringMVC事务管理器不起作用

发表于 2016-07-06

问题描述

通过Spring MVC + MySQL配置事务,事务配置没有问题,删除数据之后,抛出异常,但是事务没有回滚。

解决办法

最后发现原来是MySQL表的引擎为:MyISAM,导致不支持事务。修改对应建表语句,指定引擎为

1
ENGINE=InnoDB DEFAULT CHARSET=utf8;

原因验证

可以通过下面方式来验证,是否是这个原因导致事务不会滚。
在Navicat Premium工具中,右击对应的表,进入Object Information,进入DDL标签:
ENGINE
如果发现对应的ENGINE为MyISAM,则表示这种引擎不支持事务。

Invalid content was found starting with element 'init-param'

发表于 2016-06-28

web.xml文件中:

1
2
3
4
5
6
7
8
9
10
<servlet>
<servlet-name>Zblog</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-servlet.xml</param-value>
</init-param>
</servlet>

第六行报错,报错信息如下:

1
2
3
cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'. One of '{"http://
java.sun.com/xml/ns/javaee":run-as, "http://java.sun.com/xml/ns/javaee":security-role-ref,
"http://java.sun.com/xml/ns/javaee":multipart-config}' is expected.

解决办法:
将4、5行移到9行和10行之间,最终效果如下:

1
2
3
4
5
6
7
8
9
10
<servlet>
<servlet-name>Zblog</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>

如何正确的实现Java中的hashCode方法

发表于 2016-06-22

你知道一个对象的唯一标志不能仅仅通过写一个漂亮的equals来实现
太棒了,不过现在你也必须实现hashCode方法。

让我们看看为什么和怎么做才是正确的。

相等和哈希码

相等是从一般的方面来讲,哈希码更加具有技术性。如果我们在理解方面存在困难,我们可以说,他们通过只是一个实现细节来提高了性能。

大多数的数据结构通过equals方法来判断他们是否包含一个元素,例如:

1
2
List<String> list = Arrays.asList("a", "b", "c");
boolean contains = list.contains("b");

这个变量contains结果是true,因为,虽然”b”是不相同的实例(此外,忽略字符串驻留),但是他们是平等的。

阅读全文 »

LinkedList源码分析

发表于 2016-06-18

Java版本:

1
2
3
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

LinkedList由双向链表实现。
LinkedList主要成员变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
transient int size = 0;

/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;

/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;

//核心数据结构代码:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;

Node(Node<E> prev, E element, Node<E> next) {
this.item = element ;
this.next = next ;
this.prev = prev ;
}
}

通过定义的内部类,包括三个成员变量,数据对象,前一个节点对象,以及后一个节点对象。

add()/get()/remove()方法举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
* Appends the specified element to the end of this list.
*
* <p>This method is equivalent to {@link #addLast} .
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add} )
*/
public boolean add(E e ) {
linkLast(e);
return true ;
}

/**
* Links e as last element.
* 首先获得最后一个元素,新建一个节点newNode,
* 如果最后一个元素为空,则将newNode赋值给first
* 否则将newNode赋值给最后一个元素的next
*/
void linkLast(E e) {
final Node<E> l = last ;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l. next = newNode;
size++;
modCount++;
}


/**
* Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException {@inheritDoc}
* 检查index合法性,调用node方法
*/
public E get( int index ) {
checkElementIndex(index);
return node(index).item ;
}

/**
* Returns the (non -null) Node at the specified element index.
* 采用二分,如果index小于size >> 1(size/2),那么将从第一个元素开始往前推
* 否则,从最后一个元素往后推
*/
Node<E> node(int index ) {
// assert isElementIndex(index);

if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index ; i ++)
x = x. next;
return x ;
} else {
Node<E> x = last;
for (int i = size - 1; i > index ; i --)
x = x. prev;
return x ;
}
}

/**
* Removes the element at the specified position in this list. Shifts any
* subsequent elements to the left (subtracts one from their indices).
* Returns the element that was removed from the list.
*
* @param index the index of the element to be removed
* @return the element previously at the specified position
* @throws IndexOutOfBoundsException {@inheritDoc}
* 检查index合法性,根据index获得对应的Node元素作为参数,调用unlink方法
*/
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}

/**
* Unlinks non -null node x.
* 获得Node对象的element,前一个节点prev及后一个节点next
* 处理x的prev节点:
* 如果移除的元素为首元素(即prev为null),那么直接将节点next赋给first
* 否则,将next赋值给prev.next,并将x.prev置空
* 处理x的next节点:
* 如果移除的元素为尾元素(即next为null),那么直接将节点prev赋值给last
* 否则,将prev赋值给next.prev,并将x.next置空
*/
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item ;
final Node<E> next = x.next ;
final Node<E> prev = x.prev ;

if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}

if (next == null) {
last = prev;
} else {
next. prev = prev;
x.next = null;
}

x. item = null;
size--;
modCount++;
return element ;
}

ArrayList源码分析

发表于 2016-06-11

Java版本:

1
2
3
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

ArrayList采用动态数组实现。

ArrayList主要成员变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
* DEFAULT_CAPACITY when the first element is added.
* 底层存储数据的数组
*/
private transient Object[] elementData;

/**
* The size of the ArrayList (the number of elements it contains).
* 大小
* @serial
*/
private int size;

其中,transient表示: java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

ArrayList扩容核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @paramminCapacity the desired minimum capacity
*/
privatevoid grow(int minCapacity) {
// overflow-conscious code
intoldCapacity=elementData.length;
intnewCapacity=oldCapacity+ (oldCapacity>> 1);
if(newCapacity-minCapacity< 0)
newCapacity=minCapacity;
if(newCapacity-MAX_ARRAY_SIZE> 0)
newCapacity=hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData= Arrays.copyOf(elementData,newCapacity);
}

ArrayList默认初始容量为10,扩容机制:oldCapacity+ (oldCapacity>> 1); (初始容量*1.5),
最终的数组复制均是通过System.arraycopy()方法来复制,
其中native表示 “A native method is a Java method whose implementation is provided by non-java code.”
public static native void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);

add()、remove()方法最终均调用System.arraycopy()来实现。

add()/get()/remove()方法举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* Appends the specified element to the end of this list.
*
*@parame element to be appended to this list
*@return<tt>true</tt>(as specified by{@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size+ 1); // Increments modCount!!
elementData[size++] =e;
returntrue;
}

private void ensureCapacityInternal(int minCapacity) {
if(elementData==EMPTY_ELEMENTDATA) {
minCapacity= Math.max(DEFAULT_CAPACITY,minCapacity);
}

ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
modCount++;

// overflow-conscious code
if(minCapacity-elementData.length> 0)
grow(minCapacity);
}

/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
*@paramindex the index of the element to be removed
*@returnthe element that was removed from the list
*@throwsIndexOutOfBoundsException{@inheritDoc}
*/
publicE remove(int index) {
rangeCheck(index);

modCount++;
EoldValue= elementData(index);

intnumMoved=size-index- 1;
if(numMoved> 0)
System.arraycopy(elementData,index+1,elementData,index,
numMoved);
elementData[--size] =null;// clear to let GC do its work

returnoldValue;
}

@SuppressWarnings("unchecked")
E elementData(int index) {
return (E)elementData[index];
}

/**
* Returns the element at the specified position in this list.
*
*@param index index of the element to return
*@returnthe element at the specified position in this list
*@throwsIndexOutOfBoundsException{@inheritDoc}
*/
publicE get(int index) {
rangeCheck(index);

return elementData(index);
}
1…8910…14
漠北空城

漠北空城

69 日志
19 标签
链接
  • xyz327
© 2024 漠北空城
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4
粤ICP备18054530号-2   |     |